Назад | Перейти на главную страницу

Как в zsh перенаправить stderr на / dev / null в цикле for или foreach?

Я пытаюсь сделать то, что легко в 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 над пустым расширением ничего не делает, что нам и нужно здесь.

Парсинг 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

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

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