如何解决Shell脚本处理含特殊字符文件名时报错的问题
问题原因
你写的脚本出错是两处bash变量展开规则导致的:
- 用不带引号的
$*遍历传入参数时,bash会默认按空格、制表符、换行拆分所有参数,同时触发通配符展开,带空格、*、?这类特殊字符的文件名会被拆成多个无效参数,甚至匹配到其他无关文件。 - 循环内
rm $file同样没有加引号,哪怕你拿到了正确的文件名,到这一步也会再次触发拆分和通配符展开,导致执行报错。
修复方案
修改后的脚本如下:
#!/bin/bash for file in "$@" do rm -- "$file" done
如果不需要额外的循环逻辑,也可以直接简化为一行,效果完全一致:
#!/bin/bash rm -- "$@"
修改点说明
- 替换
$*为带双引号的"$@":带引号的$@会原样保留每个传入的参数,无视参数内的特殊字符,每个参数都会作为独立的元素传递给循环,不会拆分也不会做通配符展开。 - 给变量
$file套双引号:保证rm命令拿到的是完整的原始文件名,不会做二次解析。 - 新增
--参数:避免碰到以-开头的文件名时,rm误把文件名识别为命令选项导致报错,--代表后续所有内容都是文件名,不再解析选项。
内容的提问来源于stack exchange,提问作者user16986383
相关产品推荐
相关产品推荐

