1

次の点を考慮してください。

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

(私の読みによると)sh 言語仕様のセクション 2.3 パラグラフ 5 によると、 の算術展開はj += 1トークン認識中に行われる必要があるため、シェルが を読み取る前に処理する必要があります&。したがって、上記の行を実行するとj3 ずつインクリメントされ、echo の呼び出しごとに異なる引数が取得されるようです。(「&」が「;」に置き換えられた場合の動作です)。bash 3.2.25 では、j変更されていません。これは bash のバグですか、それとも何か誤解していますか?

4

1 に答える 1

1

そのトークン認識セクション全体は、いかなる種類の拡張やコマンド評価ではなく、解析を扱います。コンテキストの「概要」を見てください。構文解析は基本的にすべての前に行われますが、算術式の評価は通常、最後の評価ステップの1つです。ここではあまり関係ありません。

おそらく、非同期リストのサブシェルフォークの前に拡張が発生するかどうかについて実際に疑問に思っているでしょう。彼らはしません。

 $ 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
 $

展開の順序については、パラメーターの展開とコマンド置換と同時に、左から右に算術展開が実行されます(上記の2番目のループでも示されています)。

このセクションを読み間違えたのはあなただけではないと思います。これに関連するバグをいくつか報告しましたが、これは私の側のエラーであるか、POSIX以外のシェル拡張機能との不幸な相互作用が原因であることが判明しました。私見そのセクションはあまりにも簡潔です。

仕様言語または実装に問題があると思われる場合は、メーリングリストの1つでより適切な回答が見つかる可能性があります。ast-usershelp-bashaustinグループリスト

于 2012-04-16T11:11:50.153 に答える