请考虑以下事项:
for i in 1 2 3; do echo $(( j += 1 ))& done
根据(我的阅读)sh language spec,第2.3节第5段,j += 1
的算术扩展应该在令牌识别期间进行,因此应该在shell读取{{}之前进行处理{1}}。因此,执行上面的行似乎应该将&
增加3,并且每次调用echo都应该获得不同的参数。 (如果'&'被';'替换,那么这是什么行为)。在bash 3.2.25中,j
未被修改。这是bash中的错误,还是我误解了什么?
答案 0 :(得分:1)
整个令牌识别部分处理解析,而不是扩展或任何类型的命令评估。看一下上下文的“介绍” - 基本上解决所有问题,而算术表达式的评估通常是最后一个评估步骤之一。这里并不重要。
您可能实际上想知道扩展是否发生在异步列表的子shell分支之前。他们没有。
$ 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-users,help-bash,austin group lists