Вы можете переопределить встроенную -команду, внешнюю команду или функцию с псевдонимом. Пока псевдоним выполняется, псевдоним с таким же именем не будет расширен. Таким образом, если расширение псевдонима использует имя псевдонима, это вызывает встроенную -или внешнюю команду или функцию с тем же именем. Это означает, что вы можете использовать псевдоним простым способом для передачи дополнительных параметров команде. Но вы не можете сделать намного больше из-за того, как работает расширение псевдонима — это простая замена слов без оценки.
Вы можете переопределить встроенную -команду или внешнюю команду с помощью функции. Тот факт, что в данный момент выполняется функция с определенным именем, не влияет на выполнение,и, в частности, не влияет на значение имени функции :, оно продолжает ссылаться на функцию. Рекурсивные функции не распространены в программировании оболочки, но против них нет никаких правил.
В оболочках 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
), но этого вполне достаточно для данного случая использования. Цитата из 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 . 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
Переменная оболочки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
. Если у вас нет особых причин для этого, вам не следует делать это из обычных файлов запуска оболочки.