1

考虑以下:

for i in 1 2 3; do echo $(( j += 1 ))& done

根据(我对sh 语言规范的阅读)第 2.3 节第 5 段,算术扩展j += 1应该发生在令牌识别期间,因此应该在 shell 读取&. 所以似乎执行上面的行应该增加j3 并且每次调用 echo 应该得到一个不同的参数。(如果 '&' 被 ';' 替换,这是什么行为)。在 bash 3.2.25 中,j未修改。这是bash中的错误,还是我误解了什么?

4

1 回答 1

1

整个令牌识别部分处理解析,而不是扩展或任何类型的命令评估。看一下上下文的“介绍” - 解析基本上是所有事情之前,而算术表达式的评估通常是最后的评估步骤之一。这在这里并不重要。

您实际上可能想知道扩展是否发生在异步列表的子shell fork 之前。他们没有。

 $ ksh93 -c 'typeset -i n; while ((++j%10)); do { n+=1; printf "$n "; } & done; while ((++j%10)); do : $((n++)) ${ printf "$n " >&2;} & done 2>&1; echo'
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
 $
 $ bash -c 'f() { printf "#%d %s, %s\n" "$@"; }; f 1 $BASHPID $$; f 2 $BASHPID $$ & sleep 1'      
#1 12275, 12275
#2 12276, 12275
 $

至于展开的顺序,算术展开与参数展开和命令替换同时进行,从左到右(也如上图第二个循环所示)。

我认为您不是唯一一个误读了该部分的人,我已经提交了一些与之相关的错误,这些错误要么是我的错误,要么是由于与非 POSIX shell 扩展的一些不幸交互。恕我直言,该部分太简洁了。

如果您认为规范语言或实现存在问题,您可能会在其中一个邮件列表中找到更好的答案。ast-usershelp-bashaustin 组列表

于 2012-04-16T11:11:50.153 回答