如何在Bash脚本中避免参数展开,实现无引号输入模式查找旧文件
解决Bash脚本中匹配模式被提前展开的问题
问题背景
需要编写Bash脚本实现:查找指定文件夹中修改时间超过n天的旧文件,支持可选的匹配模式(如文件扩展名),输入参数格式为天数 文件夹 [匹配模式]。但执行./a.sh 20 /home/user/ *.txt时,*会被Shell提前展开,只有当前目录无.txt文件时脚本才能正常工作。
问题根源
原脚本的核心问题是Bash的路径扩展(Globbing)机制:在执行脚本前,Shell会自动将*.txt替换为当前目录下所有匹配.txt的文件名列表,导致脚本接收到的$3不是预期的匹配模式,而是多个文件名,最终使find命令执行逻辑错误。
解决方案
修改后的脚本
#!/bin/bash # 临时禁用路径扩展,防止模式被Shell提前展开 set -f # 读取输入参数 days="$1" directory="$2" pattern="${@:3}" # 恢复路径扩展,不影响脚本后续操作 set +f # 参数合法性校验 if ! [[ "$days" =~ ^[0-9]+$ ]]; then echo "错误:天数必须是正整数" exit 1 fi if [ ! -d "$directory" ]; then echo "错误:目录 '$directory' 不存在或不是有效目录" exit 1 fi # 执行文件查找逻辑 if [ -z "$pattern" ]; then find "$directory" -type f -mtime +"$days" else find "$directory" -type f -name "$pattern" -mtime +"$days" fi
关键改进点
- 临时禁用路径扩展:用
set -f关闭Shell的路径扩展功能,确保*.txt以原始字符串传递给脚本,处理完参数后用set +f恢复默认行为。 - 安全变量引用:所有变量用双引号包裹,避免空格、特殊字符引发的解析错误。
- 参数校验:增加对天数格式、目录有效性的检查,提升脚本健壮性。
替代方案(无需修改脚本)
如果不想调整脚本,也可以通过转义星号的方式避免Shell展开:
./a.sh 20 /home/user/ \*.txt
内容的提问来源于stack exchange,提问作者Sergio Manzi
相关产品推荐
相关产品推荐

