我正在尝试在 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
由于您使用的是登录脚本,因此我已尝试使其尽可能快。
这对整个伯恩家族来说应该都有效。