Временно измените / 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. Кроме того, это общесистемное решение, а не только для текущего окна терминала.


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


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", но это, вероятно, пуристическая деталь, которая не будет иметь значения на практике.
ванадий
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.