В zsh, как вы перенаправляете stderr в /dev/null в цикле for или foreach?

Я пытаюсь сделать что-то, что легко в bash: искать файлы в папке и получать их, если они существуют (и не выводить, если файлов не существует).

В борновых оболочках это как это сделать:

  if [-d /etc/profile.d]; затем
      для f в `ls -1 /etc/profile.d/*.sh 2> /dev/null`; делать, $ е
      сделанный
  фи

Я новичок в Zsh и не могу получить эквивалентную работу. Что я делаю неправильно?

if [[-d "/etc/zsh.d"]]; затем
    для файла в (ls -1 /etc/zsh.d/*.zsh 2> /dev/null); делать
        исходный файл
    сделанный
фи

потерпеть поражение: parse error near '>',

Я перепробовал много вариантов и не могу сделать его настолько гладким, как эквивалент sh / bash. Как будто перенаправление не всегда работает внутри подоболочек.

3 ответа

Решение

После более поздней электронной почты в список рассылки пользователей zsh мне было предложено почти идеальное решение проблемы:

if [[-d "/etc/zsh.d"]]; затем
  для f в /etc/zsh.d/*.zsh(N); делать
    источник $f
  сделанный
фи

(N) указывает zsh установить опцию NULL_GLOB для этого шаблона. Когда совпадений не найдено, глобус расширяется до пустой строки, а не выдает ошибку. В zsh цикл for над пустым расширением ничего не делает, и такое поведение мы хотим здесь.

анализ ls плохая идея

Вместо этого вы можете просто использовать оболочку, чтобы получить список файлов:

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

Я пытался сделать это как можно быстрее, так как вы находитесь в сценарии входа.

Это должно работать для всей семьи Борн.

Другие вопросы по тегам