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


25

最近,我正在查看一些使我感到困惑的代码,因为它可以正常工作,而且我没想到会这样。该代码简化为该示例

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

使用命令行参数运行时将其打印出来

$ ./test a b c
a
b
c

正是这一点,(对我而言)是意料之外的。为什么var未定义就不会导致错误?使用这种做法是否被认为是“好的做法”?

Answers:


27

for如果没有in value1 value2...在所有类似Bourne的壳中指定零件,则loops循环在位置参数上循环。

从70年代后期开始,在Bourne shell中就已经存在这种情况,尽管在Bourne shell中,您需要忽略这一点;(您也可以使用for i do(某些旧的ash版本除外,在该版本中需要换行符do)。

请参阅Bash for loops中“ do”关键字的目的是什么?有关更多信息,包括更令人惊讶的变体。

正在做:

for i
do
  something with "$i"
done

是个好习惯 它比通常的同等产品更具可移植性/可靠性:

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

对于Bourne shell,ksh88在某些情况下会存在一些问题(例如,$#在某些版本的Bourne shell中为0(而${1+"$@"}不是"$@"可以解决),或者$IFS在Bourne和ksh88中不包含空格),或者该nounset选项已启用,并且$#在某些shell的某些版本中bash(包括(再次${1+"$@"}作为替代方法))为0。


收到我的大脑决定停止在开始编辑了重复“回路”读这三次
三Diag(诊断)

20

这是默认行为,是的。据记载在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.

所以,当你不给它一个列表遍历,它会默认为迭代$@,阵列位置参数(abc在你的例子)。

而且此行为是由POSIX定义的,因此,就目前而言,它被认为是“良好实践”。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.