Каково правильное расположение переменной оболочки PS1?

Вы можете переопределить встроенную -команду, внешнюю команду или функцию с псевдонимом. Пока псевдоним выполняется, псевдоним с таким же именем не будет расширен. Таким образом, если расширение псевдонима использует имя псевдонима, это вызывает встроенную -или внешнюю команду или функцию с тем же именем. Это означает, что вы можете использовать псевдоним простым способом для передачи дополнительных параметров команде. Но вы не можете сделать намного больше из-за того, как работает расширение псевдонима — это простая замена слов без оценки.

Вы можете переопределить встроенную -команду или внешнюю команду с помощью функции. Тот факт, что в данный момент выполняется функция с определенным именем, не влияет на выполнение,и, в частности, не влияет на значение имени функции :, оно продолжает ссылаться на функцию. Рекурсивные функции не распространены в программировании оболочки, но против них нет никаких правил.

В оболочках POSIX вы можете заставить имя ссылаться на встроенную -внутреннюю или внешнюю команду, поместив commandперед вызовом. Другими словами, commandигнорирует псевдонимы и функции. В zsh commandвызывает вызов внешней команды (, если не установлена ​​опция posix_builtins), т. е. также обходит встроенные функции. Чтобы принудительно выполнить встроенную команду zsh, используйте встроенную команду builtin.

Это приводит к одному решению :в вашей функции-оболочке: вызовите builtin fcвместо fc.

Однако это не обязательно лучшее решение в вашем случае, потому что ваша функция будет вызываться везде, включая вызовы fcиз других функций. При переопределении встроенного поведения -я рекомендую придерживаться псевдонима. Псевдоним применяется только к тому, что вы вводите в командной строке или загружаете с помощью .(, также известного как source), а не к функциям, загружаемым с помощью autoload -U(, что является рекомендуемым способом автоматической загрузки функции ). Поэтому определите псевдоним fc, который вызывает вашу функцию-оболочку, и дайте вашей функции-оболочке другое имя.

fc_wrapper () {
    for x; do
        if [[ "${x}" == -*W* ]]; then
            echo >&2 "I'm sorry Dave. I'm afraid I can't do that."
            return 1
        fi
    done
    \fc "${@}"
}
alias fc=fc_wrapper

Я поставил \fcвместо fcв определении функции. В этом нет необходимости при загрузке определения из .zshrcперед определением псевдонима, но это необходимо, например, если вы редактируете или перезагружаете определение функции во время интерактивного сеанса. Я также сделал несколько незначительных улучшений функции :

.
  • Печатать сообщение об ошибке при стандартной ошибке.
  • Если вы не выполняете задание, верните статус ошибки.
  • Также ловите такие случаи, как fc -WI. Это не полностью надежно, так как он также будет перехватывать такие вызовы, какfc -R -- -W(чтение истории из файла с именем -W), но этого вполне достаточно для данного случая использования.
4
28.10.2019, 12:16
3 ответа

Цитата из bash man -страница:

When  bash is invoked as an interactive login shell, or as a non-interactive
shell with the --login option, it first reads and executes commands from the
file  /etc/profile,  if that file exists.  After reading that file, it looks
for ~/.bash_profile, ~/.bash_login, and ~/.profile, in that order, and reads
and  executes  commands from the first one that exists and is readable.  The
--noprofile option may be used when the shell is  started  to  inhibit  this
behavior.

When  a  login  shell  exits, bash reads and executes commands from the file
~/.bash_logout, if it exists.

When an interactive shell that is not a login shell is started,  bash  reads
and  executes  commands  from /etc/bash.bashrc and ~/.bashrc, if these files
exist.  This may be inhibited by using the --norc option.  The --rcfile file
option  will  force  bash  to read and execute commands from file instead of
/etc/bash.bashrc and ~/.bashrc.

Так что многое зависит от того, как вы запускаете оболочку.

  • Если вы хотите, чтобы ваш PS1был активен во всех логинах оболочках (, например. через su - <user>или при удаленном входе через ssh), поместите его в профиль .
  • Если вы хотите, чтобы ваш PS1был активен во всех не -входных оболочках (, например. просто открыв другой терминал в среде рабочего стола ), вставьте в bashrc .
  • Если вы хотите, чтобы он был активен в обоих случаях, вам нужно будет поместить его в оба файла или (, что делают некоторые разновидности Linux, по крайней мере, в случае системного -широкого /etc /profile и /etc/bash.bashrc ), источник .bashrc в .profile .
4
27.01.2020, 20:45

PS1должно быть в .bashrc. Вы также можете установить его в .profile.

Исходники Debian.bashrc оттуда:

# if running bash
if [ -n "$BASH_VERSION" ]; then
    # include.bashrc if it exists
    if [ -f "$HOME/.bashrc" ]; then
   . "$HOME/.bashrc"
    fi
fi
2
27.01.2020, 20:45

Переменная оболочкиPS1должна быть установлена ​​в ~/.bashrcдля оболочки bash, так как это файл инициализации, который считывается для интерактивных сеансов оболочки.

Обратите внимание, что эта переменная является переменной оболочки , а не переменной среды (. Не имеет смысла позволять дочерним процессам наследовать ее значение, и ее использует только текущая оболочка ). Поэтому его не нужно экспортировать с export.

Связанные:

Вам не нужно запускать bashиз любого из файлов запуска оболочки. Запуск конкретной оболочки из~/.profile(или соответствующего файла, связанного с вашей оболочкой входа в систему ), может быть оправдан, если система, в которой вы работаете, не позволяет вам изменить вашу оболочку входа в систему. Следует соблюдать осторожность, чтобы не запускать другую оболочку, если эта оболочка уже выполняет файл, иначе вы можете оказаться в своего рода бесконечном цикле.

Код exec, который вы добавляете в свой ~/.bash_profile, никогда не понадобится. Я предполагаю, что это способ получить ~/.bashrcдля разбора (он запускает интерактивную оболочку, а интерактивные bashоболочки читают~/.bashrc). Лучшим способом сделать это было бы иметь один из файлов источником другого, например, используя это в~/.bash_profile:

if [[ -f $HOME/.bashrc ]]; then
    source "$HOME/.bashrc"
fi

Затем установите PS1в ~/.bashrc(, нет необходимости прикасаться к HOMEилиTERM).

Еще одна вещь, которую делает команда, — это удаление всех других переменных среды с помощью env -i. Если у вас нет особых причин для этого, вам не следует делать это из обычных файлов запуска оболочки.

14
27.01.2020, 20:45

Теги

Похожие вопросы