为什么 for 循环不需要显式指定循环变量的值集?

为什么 for 循环不需要显式指定循环变量的值集?

我读了一条命令https://unix.stackexchange.com/a/175845/674

为什么可以

$ bash -c 'for f do echo "$f";done' bash a b c
a
b
c

输出与

$ bash -c 'for f in "$@"; do echo "$f";done' bash a b c
a
b
c

为什么 for 循环不需要显式指定

  • 循环变量的值集,如in "$@"

  • ;

谢谢。

答案1

来自bash 手册页:

对于名称 [ [ 在 [ 单词 ... ] ] ; ] 要做的事情清单;完毕

in 后面的单词列表被展开,生成一个项目列表。变量名依次设置到这个列表的每个元素上,并且每次都会执行list。如果省略 in 字,则 for 命令对设置的每个位置参数执行一次 list(参见下面的参数)。 ...

然后从参数部分:

位置参数是由一位或多位数字表示的参数,而不是单个数字 0。位置参数是在调用 shell 时从其参数分配的,并且可以使用 set 内置命令重新分配。 ...

总之,in关键字和后面的分号是可选的。如果省略in关键字,则循环的参数for将从传递给 shell 的参数中获取。因此,您提供的两个代码示例是等效的。

答案2

因为POSIX语法允许它

for循环的格式如下:

for name [ in [word ... ]]
do
    compound-list
done

首先,应扩展 in 后面的单词列表以生成项目列表。然后,依次为每一项设置变量名,并每次执行复合列表。如果扩展没有产生任何项目,则复合列表不应被执行。省略:

in word...

应等于:

in "$@"

循环的正式语法for如下所示

for_clause       : For name                                      do_group
                 | For name                       sequential_sep do_group
                 | For name linebreak in          sequential_sep do_group
                 | For name linebreak in wordlist sequential_sep do_group

For是字符串 的语法标记forsequential_sep;一个或多个换行符,并且linebreak是单个可选换行符。最后do_group的就是你的do ...; done

这意味着有效for循环是

  1. 循环"$@"

    for name do ...; done
    
  2. 循环"$@"

    for name; do ...; done
    
  3. 循环空列表:

    for name in; do ...; done
    
  4. 循环非空列表:

    for name in word-list; do ...; done
    

第三种形式有效,但不执行任何操作。它的存在是为了允许单词列表扩展为空的循环。

相关内容