Я пытаюсь сделать то, что легко в bash: ищите файлы в папке и отправляйте их, если они существуют (и не выводите, если файлы не существуют).
В оболочках Борна это сделать так:
if [ -d /etc/profile.d ]; then for f in `ls -1 /etc/profile.d/*.sh 2> /dev/null`; do . $f done fi
Я новичок в zsh и не могу получить эквивалентную работу. Что я делаю не так?
if [[ -d "/etc/zsh.d" ]]; then for file in (ls -1 /etc/zsh.d/*.zsh 2> /dev/null); do source $file done fi
потерпеть поражение: parse error near '>'
.
Я перепробовал много вариантов и не могу добиться того, чтобы он был таким же плавным, как эквивалент sh / bash. Как будто перенаправление не всегда работает в подоболочках.
После последующего электронного письма в список рассылки пользователей zsh я получил почти идеальное решение проблемы:
if [[ -d "/etc/zsh.d" ]]; then for f in /etc/zsh.d/*.zsh(N); do source $f done fi
(N) указывает zsh установить параметр NULL_GLOB для этого шаблона. Если совпадений не найдено, глобус заменяется пустой строкой, а не выдаёт ошибку. В zsh цикл for над пустым расширением ничего не делает, что нам и нужно здесь.
Вместо этого вы можете просто использовать подстановку оболочки, чтобы получить список файлов:
if [[ -d "/etc/zsh.d" ]]; then
for f in /etc/zsh.d/*.zsh; do
source $f
done
fi
Что касается перенаправления, я не уверен, какова его цель в вашем примере, но если вы используете этот метод, то оболочка может выдать ошибку, а не ls
, поэтому выполните перенаправление после done
в for
петля.
Надеюсь, вы понимаете, что почти весь синтаксис sh отлично работает в zsh?
# Check dir exists then that there are files in it (silently!)
# If there are no .zsh files in /etc/zsh.d then an empty argument
# is passed to for, which then simply skips the loop
if [ -d /etc/zsh.d ]; then
for file in $(find /etc/zsh.d/ -name '*.zsh'); do
source $file
done
fi
Я постарался сделать это как можно быстрее, поскольку вы находитесь в сценарии входа в систему.
Это должно сработать для всей семьи Борнов.