![SHELL="/bin/bash" против SHELL="bash"](https://rvso.com/image/1648608/SHELL%3D%22%2Fbin%2Fbash%22%20%D0%BF%D1%80%D0%BE%D1%82%D0%B8%D0%B2%20SHELL%3D%22bash%22.png)
В чем разница между экспортом SHELL="/bin/bash" и SHELL="bash"? Раньше я это делал export SHELL="bash"
в своем .bashrc. Вроде бы работало. $($SHELL) порождал подоболочку, но ssh с аутентификацией с открытым ключом выдавал ошибку:Shell "bash" is not executable: No such file or directory
решение1
$($SHELL)
породил подоболочку
Да, потому что в оболочке $SHELL
(илилучше "$SHELL"
) расширяется до /bin/bash
или bash
в вашем случае, оба порождают Bash.
Примечание: Когда вы используете $($SHELL)
, вывод, поступающий из новой оболочки, будет выполнен после выхода из оболочки, поскольку именно так $( … )
работает подстановка команд ( ). Подстановка командимеет мало смыслаздесь и не нужно доказывать свою точку зрения.
Похоже, ваша точка зрения такова: когда SHELL="bash"
, "$SHELL"
запускает Bash, а какой-то другой инструмент (SSH-сервер?) жалуется.
Непонятно, какой инструмент жалуется. И вы не сказали нам, SHELL
подделывается ли он на стороне клиента или на стороне сервера. Нетmcveв вопросе. Также не ясно, зачем нужно устанавливать SHELL
. .bashrc
Я не собираюсь ничего из этого исследовать.
Я расскажу вам о SHELL
разнице между /bin/bash
иbash
в общем.
Цель SHELL
переменной окружения — указать на оболочку, которую вы хотите использовать. Различные программы могут использовать переменную (если она установлена), чтобы попытаться запустить выбранную вами оболочку по любой причине. Разница, которую вы заметили, возникает из-за того, что некоторые программы полагаются наPATH
переменная окружения, некоторые — нет.
Зависимость от PATH
работает следующим образом. Есть строка, которая «кодирует», какой исполняемый файл запустить. Например, строка может быть /bin/bash
, foo/bash
или bash
. Есть два случая:
- Если строка содержит ,
/
то сама строка интерпретируется как абсолютный путь (например,/bin/bash
) или относительный путь (например,foo/bash
) к исполняемому файлу. - Если строка не содержит
/
(напримерbash
, ), то она указывает только базовое имя исполняемого файла. Остальная часть пути (т. е. компонент(ы) каталога) берется изPATH
. По сути, это первый каталог, указанный в ,PATH
который содержит исполняемый файл с указанным базовым именем. В зависимости отPATH
,bash
может быть решен как/bin/bash
,/home/you/bin/bash
,./bash
(редко) или вообще не выводится (вызывая ошибкуcommand not found
или подобную ошибку).
Оболочки полагаются на PATH
, поэтому в оболочке bash
(введенной буквально или появляющейся из расширения $SHELL
или чего-то еще) находит /bin/bash
или /some/other/path/to/bash
в разумно настроенной системе.
Инструменты, которые не полагаются на, PATH
обрабатывают строку как путь (имя_пути). Это не имеет значения для строки, содержащей /
. Это имеет огромное значение для строки, не содержащей /
. Если строка является bash
и она интерпретируется непосредственно как путь, это эквивалентно тому, ./bash
что означает «файл с именем bash
в текущем рабочем каталоге».
То, что вызвало ошибку, по-видимому, извлекло содержимое переменной SHELL
и использовало его в качестве пути, не полагаясь на PATH
переменную.
Это было правильное решение. Примечание POSIXуказываетSHELL
как:
Эта переменная должна представлять путь к предпочитаемому пользователем интерпретатору командного языка.
Расследовать "имя_пути" и "разрешение имени пути", они не полагаются на PATH
. Любой инструмент, использующий SHELL
переменную, должен обрабатывать ее содержимое непосредственно как имя пути.
Когда SHELL="bash"
в оболочке "$SHELL"
запускается Bash только потому, что $SHELL
расширяетсякак и любая другая переменнаяи затем bash
лечитсякак и любая другая команда, не содержащая/
. Так что это как-то случайно.
Если я правильно понимаю документацию POSIX, то следует использовать SHELL="bash"
только если вы имеете в виду SHELL="./bash"
. Даже если вы имеете в виду это, лучше использовать путь с /
, так что механика в оболочке, где PATH
может быть использовано, не мешает тому, как SHELL
следует интерпретировать.
Скорее всего, вы не хотите ./bash
. Вы хотите /bin/bash
, поэтому используйте именно это.