Какая цель делает [ -n "$PS1" ]
в [ -n "$PS1" ] && source ~/.bash_profile;
служите? Эта линия входит в .bashrc
из точечных файлов репо .
10
Это проверяет, является ли оболочка интерактивной или нет. В этом случае, только поиск ~/.bash_profile
файла, если оболочка является интерактивной.
Смотрите "Является ли эта оболочка интерактивной?" в руководстве по bash, которое цитирует эту специфическую идиому. (Также рекомендуется проверить, является ли оболочка интерактивной, проверив, $-
содержит ли специальная переменная i
символ, что является лучшим подходом к этой проблеме.)
( export PS1='abc$ '; bash -c 'echo "[$PS1]"' )
которой просто печатает[]
. Кажется , ЗШ не делает то же самое, по крайней мере , из эксперимента ... В любом случае, намерение из[ -n "$PS1" ]
, чтобы проверить , является ли интерактивной оболочкой или нет.bash
сбрасывает PS1, когда неинтерактивный (опечатка в вашем предыдущем комментарии) является ошибкой IMO, PS1 не является специфичной для bash переменной, он не имеет смысла ее сбрасывать. Это единственная оболочка, которая делает это (хотяyash
также устанавливаетPS1
значение по умолчанию, даже когда не является интерактивным).[[ $- = *i* ]] && source ~/.bash_profile
).[ -n "${PS1}" ]
, но я все же обновил свой ответ, чтобы подчеркнуть, что руководство по bash также предлагает / рекомендует проверять,$-
является ли оболочка интерактивной, надеюсь, вы найдете, что это улучшает ответ. Ура!Что это делает
Это широко распространенный способ проверки, является ли оболочка интерактивной. Помните, что он работает только в bash, он не работает с другими оболочками. Так что это нормально (если глупо) для
.bashrc
, но это не сработает.profile
(это читается sh, а bash - только одна из возможных реализаций sh, и не самая распространенная).Почему это работает (только в bash!)
Интерактивная оболочка устанавливает переменную оболочки
PS1
в строку приглашения по умолчанию. Поэтому, если оболочка является интерактивной,PS1
она установлена (если только пользователь.bashrc
не удалил ее, чего не могло быть еще наверху.bashrc
, и вы могли бы подумать, что в любом случае это глупо).Обратное утверждение верно для bash: неинтерактивные экземпляры bash сбрасываются
PS1
при запуске. Обратите внимание, что это поведение характерно для bash и, возможно, является ошибкой (почему быbash -c '… do stuff with $var…'
не работать, когдаvar
естьPS1
?). Но все версии bash вплоть до 4.4 (включая последнюю версию, как я пишу) делают это.Многие системы экспортируются
PS1
в окружающую среду. Это плохая идея, потому что много разных оболочек используют,PS1
но с другим синтаксисом (например , экранирование приглашений bash полностью отличается от экранирования приглашений zsh ). Но это достаточно широко распространено, так что на практикеPS1
его установка не является надежным индикатором интерактивности оболочки. Оболочка может быть унаследованаPS1
от среды.Почему это (неправильно) используется здесь
.bashrc
это файл, который bash читает при запуске, когда он интерактивный. Менее известным фактом является то, что bash также читает.bashrc
оболочку входа в систему, и эвристика bash заключает, что это удаленный сеанс (bash проверяет, является ли его родительrshd
илиsshd
). Во втором случае маловероятно, чтоPS1
это будет установлено в среде, потому что ни один точечный файл еще не запущен.Однако то, как код использует эту информацию, контрпродуктивно.
.bash_profile
в этой оболочке. Но.bash_profile
это скрипт для входа в систему. Он может запускать некоторые программы, которые предназначены для запуска только один раз за сеанс. Это может переопределить некоторые переменные среды, которые пользователь преднамеренно установил на другое значение перед запуском этой оболочки. Запуск.bash_profile
в оболочке без входа в систему разрушителен..bash_profile
. Но это тот случай, когда загрузка.bash_profile
может быть полезной, потому что неинтерактивная оболочка входа в систему не загружается автоматически/etc/profile
и~/.profile
.Я думаю, что причина, по которой люди делают это, - для пользователей, которые входят через GUI (очень распространенный случай) и которые
.bash_profile
вместо этого помещают свои переменные параметры среды.profile
. Большинство механизмов входа в GUI вызывают,.profile
но не вызывают.bash_profile
(чтение.bash_profile
потребует запуска bash как части запуска сеанса, а не sh). При такой конфигурации, когда пользователь открывает терминал, он получает свои переменные среды. Однако пользователь не получит свои переменные среды в приложениях с графическим интерфейсом, что является очень распространенным источником путаницы. Решением здесь является использование.profile
вместо.bash_profile
установки переменных среды. Добавление моста между.bashrc
и.bash_profile
создает больше проблем, чем решает.Что делать вместо
Существует простой, портативный способ проверить, является ли текущая оболочка интерактивной: проверьте,
-i
включена ли эта опция .Это полезно
.bashrc
для чтения.profile
только в том случае, если оболочка не является интерактивной, то есть противоположна тому, что делает код! Читайте,.profile
если bash является (неинтерактивной) оболочкой для входа, и не читайте ее, если это интерактивная оболочка.источник
[[ -o interactive ]]
(ksh, bash, zsh) илиcase $- in (*i*) ...; esac
(POSIX)PS1
если не работает в интерактивном режиме. Это достаточно просто проверить:PS1=cuckoo bash -c '[ -n "${PS1}" ] && echo "PS1=[${PS1}]"'
ничего не печатает, аPS1=cuckoo bash -i -c '[ -n "${PS1}" ] && echo "PS1=[${PS1}]"'
печатает значение$PS1
set в ваших файлах запуска bash (строка «кукушка» не печатается).$-
содержитi
с интерактивной оболочкой.[ -n "${PS1}" ]
неправильный вызов заходит слишком далеко, ведь он ломается только тогда, когда кто-то экспортирует PS1 (что в своем ответе вы говорите, что это плохая идея, и даже вдумываетесь в причины), и это не влияет В любом случае, bash (поскольку он сбрасывает PS1 и PS2, если оболочка не является интерактивной.) Возможно, лучше использовать слово «обескураженный» или говорить об «ограничениях» подхода. Я не думаю, что это "неправильно" вообще. Если что-то не так экспортирует PS1, это точно! В любом случае, спасибо, что углубились в детали этого.Кажется, что эта странная концепция является результатом того факта, что
bash
она начиналась не как клон оболочки POSIX, а какBourne Shell
клон.В результате, интерактивное поведение POSIX (которое
$ENV
вызывается для интерактивных оболочек) было добавлено позжеbash
и широко не известно.Существует одна оболочка, которая обеспечивает подобное поведение. Это
csh
и гранты csh, которые$prompt
имеют конкретные значения:Но это не относится ни к Bourne Shell, ни к POSIX-оболочкам.
Для оболочки POSIX единственный предоставленный метод - поместить код для интерактивных оболочек в файл:
это имеет конкретное имя оболочки. Это например
Другие люди упоминали флаг оболочки
-i
, но он не пригоден для надежного программирования. POSIX не требует, чтобы этоset -i
работало и не$-
содержалоi
интерактивных оболочек. POSIX просто требует,sh -i
чтобы оболочка переводилась в интерактивный режим.Поскольку переменная
$PS1
может быть импортирована из среды, она может иметь значение даже в неинтерактивном режиме. Тот факт, чтоbash
unset
sPS1
в любой неинтерактивной оболочке не предоставляется стандартом и не делается никакой другой оболочкой.Таким образом, чистое программирование (даже с
bash
) состоит в том, чтобы поместить команды для интерактивных оболочек$HOME/.bashrc
.источник
Сначала я расскажу о том, что Debian, а также большую часть времени Ubuntu устанавливает для bash. И последнее касается других систем.
В настройках файлов запуска оболочки есть много мнений.
У меня тоже есть свое мнение, но я постараюсь показать существующие примеры правильных настроек.
Я буду использовать debuan, так как примеры его файлов довольно легко найти.
И Debian активно используется, поэтому настройки были хорошо протестированы,
Какова цель проверки, что PS1 установлен?
Только чтобы узнать, является ли оболочка интерактивной.
По умолчанию
/etc/profile
в Debian и Ubuntu (из / usr / share / base-files / profile):If читается: если интерактивный (PS1 установлен по умолчанию) и это оболочка bash (но не действует по умолчанию
sh
), то измените PS1 на новый (не по умолчанию).Значение по умолчанию
/etc/bash.bashrc
в Debian также содержит:Что довольно ясно в том, что он делает: если интерактивный не источник (остальное).
Тем не менее, в
/etc/skel/.bashrc
пример правильного пути к испытанию для интерактивной оболочки ( с помощью$-
):Это должно ясно показать, почему PS1 и одна альтернатива.
Правильный порядок
Настройки, о которых вы сообщаете, следует избегать.
Порядок (от системных настроек и более конкретных пользовательских настроек (для Баш)) является
/etc/profile
,/etc/bash.bashrc
,~/.profile
и , наконец~/.bashrc
. Это помещает самые широкие эффекты (и для большего количества оболочек) в/etc/profile
(который принадлежит root), за которым следует/etc/bash.bashrc
(который также принадлежит root), но влияет только на bash. Затем перейдите к личным настройкам$HOME
, первый~/.profile
для большинства оболочек и~/.bashrc
(почти эквивалентный~/.bash_profile
), специфичный только для bash.Поэтому неправильно источник
~/.bashrc
в~/.profile
это трансформирует специфичный для установки Баша к более общим , что пользователю затрагивают более оболочки . За исключением случаев, когда сделано так :Он проверяет, что bash работает, и загружается только
.bashrc
в этом случае.Это исходное решение от Debian. Обоснование объясняется здесь .
На самом деле, обратный поиск
~/.profile
в~/.bash_profile
(или~/.bashrc
) только повторяет применение общих правил, которые должны были быть уже загружены в конкретный вариант использования, и, следовательно, «не так уж плохо» (я не говорю «хорошо»). И я не говорю «хорошо», потому что это может вызвать зацикливание источников файлов. Например, когда подкаталог загружает родительский элемент, это цикл каталога.И именно в этом кросс-поиске смысл проверки интерактивной оболочки имеет смысл.
~/.bashrc
Загружается только интерактивная оболочка , но она, в свою очередь, может загружаться~/.profile
(или наоборот), и в этом случае можно использовать проверку интерактивной оболочки.источник