如何迭代Bash脚本中的参数
  我有一个复杂的命令,我想创建一个shell / bash脚本。  我可以很容易地以$1的$1写出来: 
foo $1 args -o $1.ext
我希望能够将多个输入名称传递给脚本。 什么是正确的做法?
当然,我想处理其中有空格的文件名。
  使用"$@"来表示所有参数: 
for var in "$@"
do
    echo "$var"
done
这将迭代每个参数并将其打印在单独的行上。 $ @的行为与$ *相似,除了引用时,如果参数中有空格,则正确分解参数:
sh test.sh 1 2 '3 4'
1
2
3 4
重写VonC现在删除的答案。
Robert Gamble简洁的回答直接解决了这个问题。 这个放大了一些与包含空格的文件名有关的问题。
另请参阅:/ bin / sh中的$ {1:+“$ @”}
  基础论文: "$@"是正确的, $* (无引号)几乎总是错的。  这是因为当参数包含空格时, "$@"可以正常工作,当它们不包含空格时与$*的作用相同。  在某些情况下, "$*"也可以,但"$@"通常(但不总是)在相同的地方工作。  不加引号, $@和$*是等价的(并且几乎总是错误的)。 
  那么, $* , $@ , "$*"和"$@"之间的区别是什么?  它们都与'壳的所有论点'有关,但它们做不同的事情。  当没有引用时, $*和$@做同样的事情。  他们将每个“单词”(非空白序列)视为一个单独的参数。  不过,引用的表单有很大不同: "$*"将参数列表视为一个单独的空格分隔的字符串,而"$@"将参数与命令行中指定的参数几乎完全相同。  当没有位置参数时, "$@"扩展到什么都没有;  "$*"扩展为一个空字符串 - 是的,有一个区别,虽然它很难察觉它。  见下文的详细信息,在引入(非标准)的命令之后al 。 
  第二篇论文:如果你需要用空格处理参数然后将它们传递给其他命令,那么你有时需要非标准的工具来协助。  (或者你应该小心使用数组: "${array[@]}"行为类似于"$@" 。) 
例:
    $ mkdir "my dir" anotherdir
    $ ls
    anotherdir      my dir
    $ cp /dev/null "my dir/my file"
    $ cp /dev/null "anotherdir/myfile"
    $ ls -Fltr
    total 0
    drwxr-xr-x   3 jleffler  staff  102 Nov  1 14:55 my dir/
    drwxr-xr-x   3 jleffler  staff  102 Nov  1 14:55 anotherdir/
    $ ls -Fltr *
    my dir:
    total 0
    -rw-r--r--   1 jleffler  staff  0 Nov  1 14:55 my file
    anotherdir:
    total 0
    -rw-r--r--   1 jleffler  staff  0 Nov  1 14:55 myfile
    $ ls -Fltr "./my dir" "./anotherdir"
    ./my dir:
    total 0
    -rw-r--r--   1 jleffler  staff  0 Nov  1 14:55 my file
    ./anotherdir:
    total 0
    -rw-r--r--   1 jleffler  staff  0 Nov  1 14:55 myfile
    $ var='"./my dir" "./anotherdir"' && echo $var
    "./my dir" "./anotherdir"
    $ ls -Fltr $var
    ls: "./anotherdir": No such file or directory
    ls: "./my: No such file or directory
    ls: dir": No such file or directory
    $
  为什么这不起作用?  它不起作用,因为shell在扩展变量之前会处理引号。  所以,为了让shell注意$var嵌入的引号,你必须使用eval : 
    $ eval ls -Fltr $var
    ./my dir:
    total 0
    -rw-r--r--   1 jleffler  staff  0 Nov  1 14:55 my file
    ./anotherdir:
    total 0
    -rw-r--r--   1 jleffler  staff  0 Nov  1 14:55 myfile
    $ 
  如果你有文件名,例如“ He said, "Don't do this!" “(带引号和双引号和空格),这会变得非常棘手。 
    $ cp /dev/null "He said, "Don't do this!""
    $ ls
    He said, "Don't do this!"       anotherdir                      my dir
    $ ls -l
    total 0
    -rw-r--r--   1 jleffler  staff    0 Nov  1 15:54 He said, "Don't do this!"
    drwxr-xr-x   3 jleffler  staff  102 Nov  1 14:55 anotherdir
    drwxr-xr-x   3 jleffler  staff  102 Nov  1 14:55 my dir
    $ 
  这些shell(所有这些)并不会让它很容易处理这些东西,所以很多Unix程序在处理它们的时候并没有很好的处理。  在Unix上,文件名(单个组件)可以包含除斜杠和NUL '
