Змінити / bin / sh посилання тимчасово


9

У мене є програмне забезпечення, яке /bin/shповинно бути Bash, але для Ubuntu типовим є Dash, і я хочу тримати його за замовчуванням; Я не хочу постійно змінювати його на Bash.

Чи є спосіб змінити його лише для запущеного сеансу терміналу? Так що програма, що працює в цьому терміналі, побачить /bin/shпов'язаний з bash, але решта системи все одно побачить Dash? Або я можу обманути програмне забезпечення, щоб бачити /bin/shBash, навіть якщо його немає?

Я не писав це програмне забезпечення, а злом його використовувати /bin/bashзамість /bin/shнасправді не є варіантом.


2
Ви можете змінити його тимчасово, але не (AFAIK) обмежити область застосування лише одним сеансом терміналу. Дивіться, наприклад, / bin / sh - символічне посилання, яке не вказує на / bin / bash
steeldriver

2
Можливо, що цікавить: unix.stackexchange.com/questions/468289/…
ejjl

7
Що б ви не робили, повідомте про це як про помилку щодо відповідного програмного забезпечення. Тому що припущення /bin/sh- bash це помилка, і це створює реальні проблеми (як ви з'ясували). Якщо ніхто не скаржиться, він ніколи не зміниться.
marcelm

1
@SergiyKolodyazhnyy Якщо помилка не спричиняє проблем на єдиній платформі, яку вони підтримують, вони, ймовірно, можуть від неї піти. Це все ще помилка.
marcelm

1
Програмне забезпечення Petalinux випущено "невеликою" компанією під назвою Xilinx, і згідно з документацією підтримується Ubuntu 16.04 (разом із CentOS та RHEL), тому я б сказав, що це помилка.
corwin

Відповіді:


10

Два відповіді вже пропонують хронізувати та прив’язувати кріплення, і є третій, тісно пов'язаний варіант: монтажу просторів імен . Використовуючи unshareпрограму , ви можете створити нову область імен для кріплення, і кріплення в цьому просторі імен не впливатимуть на інші простори імен.

Наприклад, в одному терміналі я роблю:

muru|[0] ~ sudo unshare -m /bin/bash
root@muru-1604:~# sudo mount --bind /bin/bash /bin/sh
root@muru-1604:~# /bin/sh --version
GNU bash, version 4.4.18(1)-release (x86_64-pc-linux-gnu)
Copyright (C) 2016 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later 

This is free software; you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
root@muru-1604:~# sudo -iu muru
muru|[0] ~ /bin/sh --version  # propagates
GNU bash, version 4.4.18(1)-release (x86_64-pc-linux-gnu)
Copyright (C) 2016 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later 

This is free software; you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

А в іншому:

$ /bin/sh --version
/bin/sh: 0: Illegal option --

Таким чином, ви можете запустити цю негнучку програму у власному просторі імен.


14

Якщо це сценарій, просто зателефонуйте як сценарій

bash scriptname.sh

Не потрібно змінювати посилання взагалі.

Для складеного виконуваного файлу ви можете піти chroot route:

mkdir rootfs
cp -a /usr rootfs/
cp -a /lib rootfs/
cp -a /lib64 rootfs/
cp /bin/bash  rootfs/bin/sh
cp yourprogram  rootfs/
sudo chroot rootfs  sh

А потім запустіть свою програму або sudo chroot rootfs /yourprogram


Однак на практиці немає причин, чому ви не можете використовувати його /bin/bashяк символьне посилання /bin/sh. Насправді, до версії 6.10 Ubuntu використовував /bin/bashяк /bin/sh, а потім вони перейшли через /bin/shнабагато швидшу, більш швидку реалізацію POSIX /bin/sh(тобто він дотримується стандарту POSIX для того, як повинні поводитись утиліти та ОС ОС, схожі на Unix, і реалізовувати деякі їх внутрішні ресурси) і через причини переносимості. Я настійно рекомендую прочитати відповідь Гілла , а також історичні записки про те, як /bin/dashвиникло. Що стосується сумісності, то сценарії, написані для dashвикористання POSIX-функцій, працюватимуть із bashоболонкою за замовчуванням. Зазвичай проблеми викликають навпаки -bashмає функції, які не потрібні /bin/sh, як-от <<<синтаксис або масиви.

Крім того, відповідна команда, ймовірно, написана з урахуванням RHEL або CentOS, яка використовує /bin/bashяк симпосилання до /bin/sh, пропонує дві речі: вони, ймовірно, орієнтовані на конкретну ОС і не дотримуються принципів POSIX. У цьому випадку також було б непогано перевірити, що ще вимагає команда, оскільки якщо це дійсно написано з іншою ОС, ви можете зіткнутися з більшими проблемами, ніж просто повторне посилання /bin/sh.


2
ЛОЛ. Життя може бути таким простим :-)
PerlDuck

1
Ви заробили мою нагороду :)
Джошуа Беснеатте

@JoshuaBesneatte Дякую! Радий, що моя відповідь є корисною
Сергій Колодяжний,

3
+1, і може бути краще створити жорсткі посилання замість копій (через lnабо cp -l).
Девід Фоерстер

1
Розглянемо, mount --rbind --make-rslaveа не cp -r. Також можна зробити лише для читання. Також sudo chrootзапускає скрипт як корінь, який може бути не оптимальним.
Роман Одайський

5

Однією з можливостей буде прив'язка одного файлу. Щоб зробити це, ви встановите файл /bin/bashтільки над /bin/dash так bashначебто чохлів або шкур dash. Ось такі кроки (включаючи зворотний):

root@myhost:~# cd /bin

# situation before (bash and dash are different):
root@myhost:/bin# ls -l *sh*
-rwxr-xr-x 1 root root 1113504 Apr  4 20:30 bash
-rwxr-xr-x 1 root root  121432 Jan 25  2018 dash
lrwxrwxrwx 1 root root       4 Jul 13 11:38 sh -> dash
...

# mount /bin/bash over /bin/dash:
root@myhost:/bin# mount --bind /bin/bash /bin/dash

# situation now (bash and dash are the same):
root@myhost:/bin# ls -l *sh*
-rwxr-xr-x 1 root root 1113504 Apr  4 20:30 bash
-rwxr-xr-x 1 root root 1113504 Apr  4 20:30 dash
lrwxrwxrwx 1 root root       4 Jul 13 11:38 sh -> dash
...

# Now everything that runs `/bin/sh` in fact uses `/bin/bash`.

# check what the symlink "sh" says:
root@myhost:/bin# sh --version
GNU bash, version 4.4.19(1)-release (x86_64-pc-linux-gnu)
...

# undo the mount:
root@myhost:/bin# umount /bin/dash 

# situation now (bash and dash are different again):
root@myhost:/bin# ls -l *sh*
-rwxr-xr-x 1 root root 1113504 Apr  4 20:30 bash
-rwxr-xr-x 1 root root  121432 Jan 25  2018 dash
lrwxrwxrwx 1 root root       4 Jul 13 11:38 sh -> dash
...

# check what the symlink "sh" now says:
root@myhost:/bin# sh --version
sh: 0: Illegal option --

Я не намагався mount --bind /bin/bash /bin/shбезпосередньо приховати символьне посилання. Вищеописаний mountтрюк просто робить удар і тире однаковим, так що це shстосується, bashхоча це вказує dash. Крім того, це загальносистемне рішення не тільки для поточного вікна терміналу.


Треба зізнатися, це може бути надмірним, а просто змінити симпосилання тимчасово набагато простіше. Я просто хотів показати інший можливий спосіб.


1

Ви можете мати змогу змінити його лише для поточного сеансу, використовуючи псевдонім. Перш ніж запустити свою команду в терміналі:

alias sh=bash

Це буде тимчасово і активно лише в терміналі, з якого він був виконаний.

ТАКОЖ: Це НЕ ПРАЦЮЄ, якщо ваш сценарій використовує абсолютні шляхи.

Гарна ідея як така, але якщо програмне забезпечення безпосередньо викликає / bin / sh з явним іменем шляху, воно не працюватиме. У всякому разі, таке програмне забезпечення, здається, не дуже правильно розроблене, роблячи такі припущення. Я, мабуть, запустив би його із сценарію, який готує та скидає належне середовище, якби мені довелося його взагалі використовувати. - ванадій

На жаль, "зламати" скрипт, можливо, ваш єдиний варіант. За конвою з @vanadium ви можете створити такий сценарій обгортки:

#!/bin/bash
sudo ln -sf /bin/bash /bin/sh
/run/my/script
sudo ln -sf /bin/dash /bin/sh

Однак під час дії вашого сценарію краще сподіватися, що нічого в вашій системі явно не вимагає тире.


3
Гарна ідея як така, але якщо програмне забезпечення безпосередньо викликає / bin / sh з явним іменем шляху, воно не працюватиме. У всякому разі, таке програмне забезпечення, здається, не дуже правильно розроблене, роблячи такі припущення. Я, мабуть, запустив би його із сценарію, який готує та скидає належне середовище, якби мені довелося його взагалі використовувати.
ванадій

Мені було б цікаво побачити, як ви будете займатися підготовкою навколишнього середовища. Ви б використовували chroot?
Джошуа Беснеатте

У мене не було таких амбітних ідей. Я просто думав про сценарій, який тимчасово мав би посилання на bash та скидання після завершення. Головною проблемою в цьому питанні є проблема, що стосується "програмного забезпечення".
ванадій

що буде, якби щось інше потребувало тире, поки символічне посилання було переміщене .... щось на зразок ln -sf / bin / bash / bin / sh на початку, і ln -sf / bin / dash / bin / sh, коли це зроблено?
Джошуа Беснеатте

Більшість інших процесів, ймовірно, із задоволенням використовувати bash замість тире, якщо посилання буде змінено. Так, в цьому марно, але, щоб імітувати поточну ситуацію, я зробив би відносні зв'язки, тобто "cd / bin; ln -sf bash sh", але це, мабуть, пуристська деталь, яка не має значення на практиці.
ванадій
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.