bash 脚本中使用空格迭代多个参数

bash 脚本中使用空格迭代多个参数

我的 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,因为这通常是处理外来命令行参数的最佳方法。

相关内容