zsh/bash脚本无匹配*.css时循环执行失败的解决方法
解决zsh脚本中无匹配通配符时的执行失败问题
你的脚本在没有.css文件的目录里报错中断,核心原因是zsh默认开启了nomatch选项——当通配符(比如$dir/*.css)没有匹配到任何文件时,zsh不会将其展开为空列表,而是直接抛出错误终止脚本。
下面提供几种可行的解决方案:
方案一:启用nullglob选项
开启nullglob后,通配符无匹配时会展开为空,对应的for循环会直接跳过,不会执行循环体。修改后的脚本如下:
#!/bin/zsh setopt nullglob # 开启nullglob,让无匹配的通配符展开为空 for dir in ~/pococms/poco/.poco/*; do if [ -d "$dir" ]; then for file in "$dir"/*.css do v "${file}" # 无需额外判断文件是否存在,nullglob仅会传入实际存在的文件 done fi done
如果不想全局开启nullglob,可以临时设置并恢复原有配置:
#!/bin/zsh for dir in ~/pococms/poco/.poco/*; do if [ -d "$dir" ]; then # 保存当前nullglob状态 local old_nullglob=$(setopt -o | awk '/nullglob/ {print $3}') setopt nullglob for file in "$dir"/*.css do v "${file}" done # 恢复原有nullglob设置 [[ "$old_nullglob" = "off" ]] && unsetopt nullglob || setopt nullglob fi done
方案二:临时关闭nomatch选项
关闭nomatch后,无匹配的通配符会保留原字符串,配合原脚本中的-f判断即可跳过不存在的“文件”:
#!/bin/zsh for dir in ~/pococms/poco/.poco/*; do if [ -d "$dir" ]; then # 保存当前nomatch状态 local old_nomatch=$(setopt -o | awk '/nomatch/ {print $3}') unsetopt nomatch for file in "$dir"/*.css do if [ -f "$file" ]; then v "${file}" fi done # 恢复原有nomatch设置 [[ "$old_nomatch" = "on" ]] && setopt nomatch || unsetopt nomatch fi done
方案三:用find命令简化逻辑
如果你的需求是遍历.poco下所有子目录中的.css文件,直接用find命令更简洁高效,完全规避通配符匹配问题:
#!/bin/zsh find ~/pococms/poco/.poco -type f -name "*.css" -exec v {} \;
这条命令会递归查找所有符合条件的.css文件,并逐个调用v命令打开。
内容的提问来源于stack exchange,提问作者tomcam
相关产品推荐
相关产品推荐

