Bash“for”循环没有“in foo bar...”部分

Bash“for”循环没有“in foo bar...”部分

我最近正在查看一些令我困惑的代码,因为它有效,但我没想到它会有效。代码简化为这个例子

#!/bin/bash
for var;
do
  echo "$var"
done

当使用命令行参数运行时会打印它们

$ ./test a b c
a
b
c

正是这一点,(对我来说)是出乎意料的。为什么这不会导致错误,因为var未定义?使用这个被认为是“好的做法”吗?

答案1

forin value1 value2...如果在所有类似 Bourne 的 shell 中未指定任何部分,则循环将在位置参数上循环。

从 70 年代末开始,Bourne shell 中就已经存在这种情况,但在 Bourne shell 中,您需要省略它;(您也可以使用for i do(除了在某些旧的 ash 版本中,您需要在 之前添加换行符do))。

Bash for 循环中“do”关键字的用途是什么?欲了解更多信息,包括更多奇怪变种。

正在做:

for i
do
  something with "$i"
done

是很好的做法。它比通常的同类产品稍微更便携/更可靠:

for i in "$@"; do
  something with "$i"
done

Bourne shell、ksh88 在某些情况下会出现一些问题(例如,当$#Bourne shell 的某些版本中为 0 时(这${1+"$@"}不是"$@"可以解决的),或者当$IFSBourne 和 ksh88 中不包含空格字符时),或者当该nounset选项已启用,并且$#在某些 shell 的某些版本中为 0,包括bash再次${1+"$@"}作为解决方法)。

答案2

这是默认行为,是的。它记录在help关键字中for

terdon@tpad ~ $ help for
for: for NAME [in WORDS ... ] ; do COMMANDS; done
    Execute commands for each member in a list.

    The `for' loop executes a sequence of commands for each member in a
    list of items.  If `in WORDS ...;' is not present, then `in "$@"' is
    assumed.  For each element in WORDS, NAME is set to that element, and
    the COMMANDS are executed.

    Exit Status:
    Returns the status of the last command executed.

因此,当您没有为其提供要迭代的列表时,它将默认迭代$@位置参数数组(a,在您的示例中)bc

而这种行为是由 POSIX 定义所以,是的,就目前而言,这被认为是“良好实践”。

相关内容