SHELL="/bin/bash" против SHELL="bash"

SHELL="/bin/bash" против SHELL="bash"

В чем разница между экспортом 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. Есть два случая:

  1. Если строка содержит , /то сама строка интерпретируется как абсолютный путь (например, /bin/bash) или относительный путь (например, foo/bash) к исполняемому файлу.
  2. Если строка не содержит /(например 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, поэтому используйте именно это.

Связанный контент