为何在脚本中执行带通配符的ls命令仅返回首个匹配结果?
问题:为何脚本无法输出预期的文件列表?
环境与操作说明
- 目录下的文件:
newfile1 newfile2 oldfile1 oldfile2
- 使用的脚本:
arg="${1}" ls "${arg}"
- 执行脚本时输入的参数:
newfile* - 实际输出:
newfile1
- 预期输出:
newfile1 newfile2
原因分析
问题出在Shell的通配符展开机制:
当你在命令行输入./脚本名 newfile*时,Shell会先对newfile*进行通配符匹配,把它展开成匹配到的文件名列表newfile1 newfile2,再把这些作为参数传给脚本。
但你的脚本里只读取了第一个位置参数$1(也就是newfile1),剩下的newfile2会被放到$2里,但脚本完全没处理$2,所以只会输出newfile1。另外,你给${1}加了双引号,这会把$1的内容作为单个字符串处理,即使Shell展开了多个参数,脚本也只会拿到第一个。
解决方法
根据需求可以选以下几种方式:
- 让脚本接收所有位置参数,用
"$@"代表所有传入的参数,修改脚本为:
ls "$@"
这种方式能正确接收Shell展开后的所有文件名,包括带空格的文件名,是最安全的做法。
- 如果希望脚本内部处理通配符(不让Shell提前展开),可以用
eval命令(注意:eval存在安全风险,仅在你完全信任输入参数时使用):
arg="${1}" eval ls "${arg}"
此时需要用单引号把参数括起来传给脚本,比如./脚本名 'newfile*',这样Shell不会提前展开通配符,由脚本内部通过eval处理。
内容的提问来源于stack exchange,提问作者Kyle Banerjee
相关产品推荐
相关产品推荐

