我的 RaspberryPi(运行 Raspbian)有一个 bash 脚本,该脚本应该采用多个文件名作为参数,并一个接一个地播放(使用omxplayer
)。基本结构是这样的:
#!/bin/bash
for f in ${*}
do
echo "${f}";
done;
现在,当输入文件名包含空格时,我遇到问题;特别是,行为似乎不一致。假设我们有两个文件test a b
并且test d e
位于同一目录中。使用不同的参数运行上面的脚本会产生以下结果:
$ ./test test\ a\ b
test
a
b
$ ./test "test a b"
test
a
b
$ ./test test\ a*
test
a
b
$ ./test "test a*"
test
a*
但是,奇怪的是:
./test "test*"
test a b
test d e
显然,只有最后一个变体提供了预期的输出。然而,使用起来很麻烦,特别是如果您想观看单个文件(制表符补全将填写整个名称)或者文件路径中的文件夹名称之一包含空格。
我可以在 shellscript 中做哪些不同的事情,以便它始终按预期运行?特别是,两者
$./test test*
$./test test\ a\ b test\ d\ e
应该产生相同的输出
test a b
test d e
因此可以使用正常的制表符补全轻松使用该脚本。
答案1
使用"$@"
而不是${*}
(参见特殊参数在手册中)
for f in "$@"; do
echo make sure you quote your "$variables" everywhere in the loop
有一个简写(并且更便携):
for f do ...
for f; do
也可以在某些 shell 中工作,但不是标准的。
答案2
while
另一种方法是通过以下两种方式之一使用循环:
input_cmd|while read i; do
echo "$i";
done
或通过过程替换:
while read i; do
echo "$i";
done < <(input_cmd)
据我所知,后者是一种 bashism,因此它可能无法在其他 bourne 兼容 shell 中工作。
然而,由于您是从命令行获取输入,因此最好坚持使用for
上一个答案中提供的循环解决方案。
您还应该看看man xargs
,因为这通常是处理外来命令行参数的最佳方法。