Shell脚本问题:目录路径存变量后循环无法遍历子目录与文件
为什么变量存储带通配符的路径无法遍历文件?
直接写/path/to/directory/*时,shell会先执行文件名展开(把*替换成目录下的所有文件和子目录),再把这些结果作为循环的输入列表。但把带*的路径存到变量后,shell只会替换变量得到字符串/path/to/directory/*,不会再对这个字符串做通配符展开,所以循环只会把这个字符串当作单个元素处理。
解决办法
方法1:用数组存储(推荐,支持带空格的文件名)
把路径和通配符分开,用数组存储展开后的结果:
dir="/path/to/directory" # 展开通配符并存入数组 files=("$dir"/*) # 遍历数组 for f in "${files[@]}"; do echo "$f" done
如果目录为空,这个数组会包含/path/to/directory/*本身。如果不想保留这个值,可以开启nullglob选项:
shopt -s nullglob # 开启空目录时通配符返回空列表 dir="/path/to/directory" files=("$dir"/*) for f in "${files[@]}"; do echo "$f" done shopt -u nullglob # 关闭选项,避免影响后续脚本
方法2:使用eval(不推荐,有安全风险)
eval会强制shell重新解析字符串,从而展开通配符,但如果变量中包含特殊字符(如空格、引号、;等),可能会触发意外的命令执行,仅在路径确定安全时使用:
dir="/path/to/directory/*" eval "for f in $dir; do echo \$f; done"
方法3:直接展开变量(不推荐,不支持带空格的文件名)
如果路径中没有空格,可以直接不引号包裹变量,让shell在变量替换后展开通配符,但这种方式在文件名含空格时会出错:
dir="/path/to/directory/*" # 不引号包裹$dir,shell会展开通配符 for f in $dir; do echo "$f" done
内容的提问来源于stack exchange,提问作者ecjb
相关产品推荐
相关产品推荐

