Bash 迭代目录中的所有文件,或仅迭代sh中的指定文件

Bash 迭代目录中的所有文件,或仅迭代sh中的指定文件,bash,shell,Bash,Shell,我有一个目录config,其中列出了以下文件: $ ls config file one file two file three 我想要一个bash脚本,当没有参数时,它将迭代所有这些文件;当给定文件名作为参数时,我希望它迭代指定的文件 #!/bin/sh for file in ${@:-config/*} do echo "Processing '$file'" done 如上所述,如果for循环中的列表项周围没有引号,则在没有参数的情况下会产生预期的输出,但在传递参数时会中断(

我有一个目录
config
,其中列出了以下文件:

$ ls config
file one
file two
file three
我想要一个bash脚本,当没有参数时,它将迭代所有这些文件;当给定文件名作为参数时,我希望它迭代指定的文件

#!/bin/sh
for file in ${@:-config/*}
do
    echo "Processing '$file'"
done
如上所述,如果for循环中的列表项周围没有引号,则在没有参数的情况下会产生预期的输出,但在传递参数时会中断(它在空格上分割文件名)。在传递文件名时,引用列表项(“${@:-config/*}”中的文件的
)会起作用,但如果不传递,则无法展开全局


有没有办法让这两种情况都起作用?

将处理代码放入一个函数中,然后使用不同的循环调用它:

if[$#-eq 0]
然后在配置文件中查找文件/*
不处理函数“$file”
完成
“$@”中文件的else
不处理函数“$file”
完成
fi

要获得更简单的解决方案,只需修改IFS变量即可

#!/bin/bash
IFS=''
for file in ${@:-config/*}
do
    echo "Processing '$file'"
done
IFS=$' \n\t'
$IFS
是一个默认的shell变量,它列出了shell使用的所有分隔符。如果从该列表中删除空间,外壳将不再在空间上拆分。在执行函数后,应该将其设置回默认值,这样它就不会导致脚本中的其他函数在稍后出现错误行为

注意:这似乎与dash不符(我使用了debian,并且
#!/bin/sh
链接到dash)。如果使用空的
$IFS
,则传递的参数将仅作为1个文件返回。但是,如果您输入一些随机值(即
IFS=':'
),则行为将是您想要的行为(除非文件名中有


这适用于
#/bin/bash
,但如果没有给出位置参数,则显式设置位置参数;那么对于这两种情况,for循环是相同的:

[ $# -eq 0 ] && set -- config/*
for file in "$@"; do
    echo "Processing '$file'"
done

@Jidder作为参数提供的文件名在名称中有空格吗?是的,这是关键,文件名有空格;传递
script.sh“config/file one”或“config/file three”
会打断它,但列表项周围没有引号。@Jidder他是。但是,除非在脚本中引用
“$@”
,否则循环中的空格会被分割。@jidder我已经这样做了。你自己试试看。