Shell脚本检测目录tgz文件出现expected binary operator错误如何解决
问题核心原因
你使用的if [ -e ${INPUT_DIRECTORY}*tgz ]语法依赖Shell通配符展开逻辑,触发报错的根本原因是:
test命令(即[]包裹的判断逻辑)中,-e操作符仅接受单个路径参数:
- 目录下只有1个.tgz文件时,通配符展开后语句为
[ -e /指定路径/xxx.tgz ],参数数量合法,判断正常运行- 目录下有多个.tgz文件时,通配符展开后语句变为
[ -e /指定路径/a.tgz /指定路径/b.tgz ],多出来的路径参数无法被test命令识别,就会抛出expected binary operator错误- 额外隐藏bug:如果目录下没有.tgz文件,通配符会保留原字符串不展开,语句会误判存在名为
*tgz的文件
可行解决方案
下面提供3种不同适用场景的修复方案:
方案1:最简快速判断,适合仅需确认是否存在tgz文件、无需后续操作的场景
使用ls命令的返回值判断,匹配到文件返回0,无匹配返回非0,输出全部丢弃避免污染日志:if ls "${INPUT_DIRECTORY}"*.tgz >/dev/null 2>&1; then # 存在tgz文件的逻辑 fi注意
${INPUT_DIRECTORY}用双引号包裹,可避免路径含空格、特殊字符时的报错。方案2:数组匹配法,推荐绝大多数场景使用
不仅可以判断文件是否存在,还能直接拿到所有匹配的文件路径供后续操作,无语法隐患:# 开启nullglob:通配符无匹配时返回空,而非保留原字符串 shopt -s nullglob # 将所有匹配的tgz文件存入数组 tgz_list=("${INPUT_DIRECTORY}"*.tgz) # 判断数组长度是否大于0 if [ ${#tgz_list[@]} -gt 0 ]; then echo "共找到${#tgz_list[@]}个tgz文件" # 后续可直接遍历数组处理文件:for tgz in "${tgz_list[@]}"; do ... done fi # 按需恢复nullglob默认配置 shopt -u nullglob方案3:find命令法,适合需要递归搜索子目录的场景
可以灵活控制搜索深度、过滤规则,需要递归搜索时直接去掉-maxdepth 1参数即可:# 仅搜索当前目录,找到第一个匹配文件就停止,性能更高 if find "${INPUT_DIRECTORY}" -maxdepth 1 -name "*.tgz" -print -quit | grep -q .; then # 存在tgz文件的逻辑 fi
内容的提问来源于stack exchange,提问作者Emmanuel Madarassou
相关产品推荐
相关产品推荐

