На моем Arch установить /etc/bash.bashrc
и /etc/skel/.bashrc
содержать эти строки:
# If not running interactively, don't do anything
[[ $- != *i* ]] && return
На Debian /etc/bash.bashrc
есть:
# If not running interactively, don't do anything
[ -z "$PS1" ] && return
И /etc/skel/.bashrc
:
# If not running interactively, don't do anything
case $- in
*i*) ;;
*) return;;
esac
Однако согласно man bash
неинтерактивным оболочкам эти файлы даже не читаются:
When bash is started non-interactively, to run a shell script, for
example, it looks for the variable BASH_ENV in the environment, expands
its value if it appears there, and uses the expanded value as the name
of a file to read and execute. Bash behaves as if the following com‐
mand were executed:
if [ -n "$BASH_ENV" ]; then . "$BASH_ENV"; fi
but the value of the PATH variable is not used to search for the file‐
name.
Если я правильно понимаю, *.bashrc
файлы будут прочитаны только в том случае, если на BASH_ENV
них указано. Это то, что не может произойти случайно и произойдет только в том случае, если кто-то явно установил переменную соответствующим образом.
Похоже, это лишает возможности наличия сценариев, .bashrc
автоматически определяющих пользователя при настройке BASH_ENV
, что может пригодиться. Учитывая, что bash никогда не будет читать эти файлы при неинтерактивном запуске, если явно не указано иное, почему *bashrc
файлы по умолчанию запрещают это?
Ответы:
Это вопрос, который я собирался опубликовать здесь несколько недель назад. Как и тердон , я понял, что a создается
.bashrc
только для интерактивных оболочек Bash, поэтому не нужно.bashrc
проверять, работает ли он в интерактивной оболочке. Смущает то, что все дистрибутивы, которые я использую (Ubuntu, RHEL и Cygwin), имели некоторую проверку (тестирование$-
или$PS1
), чтобы убедиться, что текущая оболочка является интерактивной. Мне не нравится программирование грузового культа, поэтому я решил понять назначение этого кода в своем.bashrc
.Bash имеет специальный чехол для удаленных оболочек
Изучив проблему, я обнаружил, что удаленные оболочки обрабатываются по-разному. Хотя неинтерактивные оболочки Bash обычно не запускают
~/.bashrc
команды при запуске, особый случай возникает, когда оболочка вызывается демоном удаленной оболочки :пример
Вставьте следующее в начале пульта
.bashrc
. (Если.bashrc
используется источник.profile
или.bash_profile
, временно отключите это во время тестирования):Выполните следующие команды локально:
i
в$-
означает, что оболочка не является интерактивной .-
в$0
указывает , что оболочка не Войти оболочка .Функции оболочки, определенные в пульте дистанционного управления,
.bashrc
также могут быть запущены:Я заметил , что
~/.bashrc
это только получен , когда команда задается в качестве аргумента дляssh
. Это имеет смысл: когдаssh
используется для запуска обычной оболочки входа.profile
или.bash_profile
запуска (и.bashrc
только из источника, если это явно сделано одним из этих файлов).Основное преимущество, которое я вижу в
.bashrc
использовании удаленной команды (неинтерактивной), заключается в том, что можно запускать функции оболочки. Тем не менее, большинство команд в типичном случае.bashrc
относятся только к интерактивной оболочке, например, псевдонимы не раскрываются, если оболочка не является интерактивной.Удаленная передача файлов может быть неудачной
Обычно это не проблема, когда
rsh
илиssh
используется для запуска интерактивной оболочки входа в систему или когда неинтерактивные оболочки используются для запуска команд. Тем не менее, это может быть проблемой для таких программ, какrcp
,scp
иsftp
которые используют дистанционные оболочки для передачи данных.Оказывается, оболочка по умолчанию для удаленного пользователя (например, Bash) неявно запускается при использовании
scp
команды. Там нет упоминания об этом на странице руководства - только упоминание, котороеscp
используетсяssh
для передачи данных. Это приводит к тому, что если в нем.bashrc
содержатся какие-либо команды, которые печатаются в стандартный вывод, передача файлов завершится неудачно , например, scp завершится с ошибкой без ошибок .Смотрите также этот связанный отчет об ошибках Red Hat 15 лет назад, scp прерывается, когда в / etc / bashrc есть команда echo (которая в итоге была закрыта как
WONTFIX
).Почему
scp
иsftp
не удалосьSCP (защищенное копирование) и SFTP (защищенный протокол передачи файлов) имеют свои собственные протоколы для локального и удаленного конца для обмена информацией о передаваемых файлах. Любой неожиданный текст с удаленного конца (ошибочно) интерпретируется как часть протокола, и передача завершается неудачно. Согласно FAQ из Книги Улитки
Детали протокола SCP
Для тех, кто интересуется подробностями того, как работает SCP, я нашел интересную информацию в разделе Как работает протокол SCP, который включает подробности о запуске scp с разговорчивыми профилями оболочки на удаленной стороне? :
Заключение / TLDR
Большинство операторов в типичном
.bashrc
случае полезны только для интерактивной оболочки, но не при выполнении удаленных команд с помощьюrsh
илиssh
. В большинстве таких ситуаций установка переменных оболочки, псевдонимов и определение функций нежелательна, а печать любого текста в стандартном формате активно вредна при передаче файлов с использованием таких программ, какscp
илиsftp
. Выход из режима после проверки того, что текущая оболочка не является интерактивной, является наиболее безопасным для поведения.bashrc
.источник
Страница man не учитывает, что
bash
также есть источники.bashrc
для неинтерактивных удаленных оболочек, как вhttp://git.savannah.gnu.org/cgit/bash.git/tree/shell.c#n1010
http://git.savannah.gnu.org/cgit/bash.git/tree/shell.c#n1050
источник
.bash_profile
будет демонстрировать такое же поведение.rsh
(которые я никогда не использовал) источники~/.bashrc
? И что, по сути, дистрибутивы Linux блокируют его наbash
случай, если кто-нибудь когда-нибудь попытается запустить скриптrsh
?ssh server
не должен касаться,.bashrc
так как это оболочка входа в систему в любом случае. Только если ваша система не относится к тем источникам, из которых ~ / .bashrc`~/.profile
. Иssh server command
даже не должен этого делать. Конечно, не в моей системе.bash
источником, а не сrsh
источником. :) Комментарий относится и к томуssh
, что он был написан очень давно. Смотрите обновленный ответ с большим количеством источников.echo
в самый верх/etc/bash.bashrc
и~/.bashrc
(до интерактивных тестов оболочки), а затем ssh в целевую машину сssh server hostname
и во времяhostname
работы, я не увидел ни одного из моих эхо-сигналов. Разве это не моеshell_level
(что бы это ни было)<2
?По соглашению,
.bashrc
это место, где пользователь хранит конфигурацию настройки для оболочки.Этими настройками конфигурации могут быть переменные среды, псевдонимы, необычные приглашения. С неинтерактивной оболочкой эти недостатки бессмысленны. Более того, неинтерактивная оболочка может вызываться во многих контекстах, вы не уверены, что эти переменные среды могут привести к ложноотрицательному случаю или даже уязвимы для безопасности.
Ближайший пример - псевдоним:
Тогда он навсегда повесит вашу неинтерактивную оболочку.
Таким образом, проверка выполняется наверху,
.bashrc
чтобы гарантировать, что у нас не будет проблем.Поскольку оболочку можно назвать неинтерактивной оболочкой входа в систему , поэтому явное использование блоков
*bashrc
не имеет смысла.Когда оболочка называется не-интерактивная оболочка , это источник
/etc/profile
, то источник первым нашел в~/.bash_profile
,~/.bash_login
и~/.profile
:Ничто не препятствует получению этих файлов
.bashrc
самим, поэтому проверка внутри.bashrc
более безопасна и упрощает задачу.источник
*bashrc
файлов. Мой вопрос заключается в том, почему различные поставщики Linux сталкиваются с проблемой явной блокировки неинтерактивных оболочек от чтения этих файлов, если эти файлы в любом случае не читаются неинтерактивными оболочками..bash_profile
, который может быть источником.bashrc
.$BASH_ENV
. Оба*profile
и*bashrc
игнорируются. Или, по крайней мере, так говорится на странице руководства. Однако, как показал Микель, страница справочника может быть лживой.bash -l -c :
вызвать неинтерактивную оболочку входа?--login
100 раз, но, видимо, она никогда не регистрировалась. Спасибо!