Почему удаленный источник Bash .bash_profile вместо .bashrc

24

Руководство Bash говорит:

Bash пытается определить, когда он запускается со своим стандартным входом, подключенным к сетевому соединению, как при выполнении демоном удаленной оболочки, обычно rshd, или демоном защищенной оболочки sshd. Если Bash определяет, что он выполняется таким образом, он читает и выполняет команды из ~ / .bashrc, если этот файл существует и доступен для чтения.

Это источники Bash ~/.bashrc:

ssh user@host :

Но это источники Bash ~/.bash_profile:

ssh user@host

Я не вижу разницы в этих двух командах согласно спецификации. Разве stdin не подключен к сетевому соединению в обоих случаях?

Cyker
источник
2
Хотя это не то, о чем вы спрашиваете, я хотел бы отметить, что хорошей практикой является получение исходного кода .bashrc из .bash_profile . Таким образом, настройки из .bashrc будут применены независимо от того, запущена ли bash как оболочка входа или не входящая в систему.
Илмари Каронен

Ответы:

44

Оболочка входа сначала читает, /etc/profileа затем ~/.bash_profile.

Оболочка без входа в систему читает /etc/bash.bashrcи затем ~/.bashrc.

Почему это важно?

Из-за этой строки в man ssh:

Если указана команда , она выполняется на удаленном хосте вместо оболочки входа в систему.

Другими словами, если команда ssh имеет только параметры (не команду), например:

ssh user@host

Это запустит оболочку входа в систему, оболочка входа в систему читает ~/.bash_profile.

Команда ssh, которая имеет команду , например:

ssh user@host :

Где команда :(или ничего не делать).
Это не запустит оболочку входа в систему, поэтому ~/.bashrcэто то, что будет прочитано.


Удаленный ввод

Предоставленное tty-соединение для / dev / stdin на удаленном компьютере может быть действительным tty или чем-то другим.

Для:

$ ssh sorontar@localhost
/etc/profile sourced

$ ls -la /dev/stdin
lrwxrwxrwx 1 root root 15 Dec 24 03:35 /dev/stdin -> /proc/self/fd/0

$ ls -la /proc/self/fd/0
lrwx------ 1 sorontar sorontar 64 Dec 24 19:34 /proc/self/fd/0 -> /dev/pts/3

$ ls -la /dev/pts/3
crw--w---- 1 sorontar tty 136, 3 Dec 24 19:35 /dev/pts/3

Который заканчивается TTY (не сетевым подключением), как его видит запущенный bash.

Для соединения SSH с помощью команды:

$ ssh sorontar@localhost 'ls -la /dev/stdin'
sorontar@localhost's password: 
lrwxrwxrwx 1 root root 15 Dec 24 03:35 /dev/stdin -> /proc/self/fd/0

Список TTY начинается так же, но обратите внимание, что / etc / profile не был получен.

$ ssh sorontar@localhost 'ls -la /proc/self/fd/0'
sorontar@localhost's password:
lr-x------ 1 sorontar sorontar 64 Dec 24 19:39 /proc/self/fd/0 -> pipe:[6579259]

Что говорит оболочке, что соединение представляет собой канал (не сетевое соединение).

Таким образом, в обоих тестовых случаях оболочка не может знать, что соединение из сети и, следовательно, не читает ~/.bashrc(если мы говорим только о соединении с сетью). Он читает ~ / .bashrc, но по другой причине.

sorontar
источник
Разве случай без аргументов также не подходит для работы со стандартным входом, подключенным к сетевому соединению и, таким образом, для ~/.bashrcчтения?
Cyker
@Cyker Предполагается, что оболочка будет stdin подключена к сети . Почему вы так думаете? (Ответ отредактирован, пожалуйста, прочитайте).
Соронтар
Отредактированная часть интересна. Похоже, ssh не беспокоится о pty при простом выполнении команды.
Cyker
8

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


Причиной наличия двух разных файлов запуска ("profile" и "rc") является то, что в прошлом обычным способом работы на машине было:

  1. Войдите в систему с какого-то реального терминала или другой рабочей станции и получите оболочку входа . Эта оболочка будет вызывать /etc/profileи ~/.profileнастраивать среду для пользователя.

  2. Вызвать среду, в которую хочет войти пользователь. Эта среда может быть Xorg, но в большинстве случаев это был мультиплексор, такой как экран GNU.

  3. Среда (например, экран GNU) будет затем вызывать дополнительные (не входящие в систему) оболочки, которые наследуют среду от родительской оболочки входа.

Это был обычный способ входа в машину UNIX в течение того времени , когда cshи в bashнастоящее время разрабатываются. Поэтому считалось расточительным читать ~/.profileснова в оболочках, которые все равно наследовали окружающую среду.

bashзатем добавлена ~/.bashrcдополнительная конфигурация для этих оболочек без входа в систему. cshtcsh) никогда не добавлял какой-либо "rc" -файл для оболочек без входа в систему. Обратите внимание, что csh/ tcshне являются оболочками, совместимыми с оболочкой Борна (которая является частью POSIX) bash. Другая совместимая с bourne оболочка kshдобавила переменную окружения (называемая ENV), которая, если она была определена, использовалась бы в качестве файла команд запуска ("rc") для отсутствия входа в систему ksh.

Так что да, более новые версии оболочек Борна добавили дополнительный файл конфигурации для удобства псевдонимов и других быстрых опций, которые будут присутствовать внутри оболочек, мультиплексированных экраном GNU (или аналогичными), но не присутствующих в оболочке, которую вы получаете при первом входе в машина.

С появлением менеджеров графического отображения (GDM) различие между файлами «profile» и «rc» стало бессмысленным, потому что GDM будет иметь свои собственные файлы инициализации (например, ~/.xinitи ~/.xsession). Тогда оболочки, указанные внутри GDM, могут быть оболочками для входа или не входа в зависимости от прихотей пользователя, и случай, когда оболочка без регистрации всегда будет иметь родителя, который является оболочкой входа, больше не соответствует действительности.

дополнительный

Одна из моих любимых таблиц о сравнении файлов запуска оболочки показывает, как оболочки, совместимые с оболочкой bourne, используют profileфайлы, а другие - нет. Это связано с тем, что в прошлом исходная оболочка (та, которая запустила мультиплексирование) должна была быть оболочкой, совместимой с bourne.

grochmal
источник