![在 zsh 中,如何在 for 或 foreach 循环内将 stderr 重定向到 /dev/null?](https://linux22.com/image/609751/%E5%9C%A8%20zsh%20%E4%B8%AD%EF%BC%8C%E5%A6%82%E4%BD%95%E5%9C%A8%20for%20%E6%88%96%20foreach%20%E5%BE%AA%E7%8E%AF%E5%86%85%E5%B0%86%20stderr%20%E9%87%8D%E5%AE%9A%E5%90%91%E5%88%B0%20%2Fdev%2Fnull%EF%BC%9F.png)
我正在尝试在 bash 中完成一些简单的事情:在文件夹中查找文件,如果存在则查找它们(如果不存在文件则不输出)。
在 Bourne Shell 中,操作方法如下:
如果 [ -d /etc/profile.d ]; 那么 对于 `ls -1 /etc/profile.d/*.sh 2> /dev/null` 中的 f;执行 .$f 完毕 菲
我是 zsh 新手,无法使用等效功能。我做错了什么?
如果 [[ -d "/etc/zsh.d" ]]; 那么 对于文件(ls -1 /etc/zsh.d/*.zsh 2> /dev/null);执行 源$文件 完毕 菲
失败:parse error near '>'
。
我尝试过许多变体,但无法让它像 sh/bash 等效版本那样流畅。就好像重定向在子 shell 中并不总是有效一样。
答案1
在后来向 zsh 用户邮件列表发送了一封电子邮件后,我得到了该问题的近乎理想的解决方案:
如果 [[ -d "/etc/zsh.d" ]]; 那么 对于 /etc/zsh.d/*.zsh(N) 中的 f;执行 来源 $f 完毕 菲
(N) 告诉 zsh 为该模式设置 NULL_GLOB 选项。当未找到匹配项时,glob 将扩展为空字符串,而不是抛出错误。在 zsh 中,对空扩展的 for 循环不执行任何操作,这正是我们在此处想要的行为。
答案2
相反,你可以使用 shell 通配符来获取文件列表:
if [[ -d "/etc/zsh.d" ]]; then
for f in /etc/zsh.d/*.zsh; do
source $f
done
fi
至于重定向,我不确定它在您的例子中的目的是什么,但是如果您使用此方法,那么 shell 可能会抛出错误,而不是,因此在循环ls
之后执行重定向。done
for
答案3
我希望你明白几乎所有的 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
由于您使用的是登录脚本,因此我已尝试使其尽可能快。
这对整个伯恩家族来说应该都有效。