Временно измените / bin / sh ссылку

9

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

Есть ли способ изменить его только для запущенной терминальной сессии? Таким образом, программа, запущенная в этом терминале, увидит, что она /bin/shсвязана с bash, а остальная часть системы все еще увидит Dash? Или я могу обмануть программное обеспечение, чтобы оно выглядело /bin/shкак Bash, даже если его нет?

Я не писал это программное обеспечение, и взломать его для использования, /bin/bashа /bin/shне на самом деле вариант.

Корвин
источник
2
Вы можете временно изменить его, но не ограничивайте (AFAIK) область действия одним сеансом терминала. Смотрите, например, / bin / sh - символическая ссылка, которая не указывает на / bin / bash
steeldriver
2
Возможно, интерес: unix.stackexchange.com/questions/468289/…
ejjl
7
Что бы вы ни делали, также сообщите об этом как об ошибке для рассматриваемого программного обеспечения. Потому что предположить /bin/sh, bash что это ошибка, и это вызывает реальные проблемы (как вы выяснили). Если никто не жалуется, он может никогда не измениться.
марта
1
@SergiyKolodyazhnyy Если ошибка не вызывает проблем на единственной платформе (ях), которую они поддерживают, то они, вероятно, могут сойти с рук. Это все еще ошибка, хотя.
Марсель
1
Это программное обеспечение Petalinux, выпущенное «небольшой» компанией под названием Xilinx, и согласно документации поддерживается Ubuntu 16.04 (наряду с CentOS и RHEL), так что я бы сказал, что это ошибка.
Корвин

Ответы:

10

В двух ответах уже предлагается chrooting и bind mounts, и есть третий, тесно связанный вариант: mount namespaces . Используя 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:

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/bashas /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запускает скрипт как root, что может быть неоптимально.
Роман Одайский
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трюк просто делает bash и dash идентичными, так что это shотносится, bashхотя и указывает на dash. Кроме того, это общесистемное решение, а не только для текущего окна терминала.


Я должен признаться, это может быть излишним, и просто временно изменить символическую ссылку гораздо проще. Я просто хотел показать другой возможный путь.

PerlDuck
источник
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?
Джошуа Беснеатте,
У меня не было таких амбициозных идей. Я просто думал о сценарии, который временно имел бы sh ссылку на bash и сбросил, когда все будет готово. Я думаю, что главная проблема в этом вопросе связана с «частью программного обеспечения».
ванадий
что произойдет, если что-то еще понадобится тире, пока символическая ссылка была перемещена .... что-то вроде ln -sf / bin / bash / bin / sh в начале и ln -sf / bin / dash / bin / sh, когда закончите?
Джошуа Беснеатте
Большинство других процессов, вероятно, с радостью будут использовать bash вместо dash, если ссылка будет изменена. Да, напрасно, но чтобы имитировать текущую ситуацию, я бы сделал относительные ссылки, например, "cd / bin; ln -sf bash sh", но это, вероятно, пуристическая деталь, которая не будет иметь значения на практике.
ванадий