
なぜ
for i in {1..5}; do x="${i}" echo "$x"; done
出力なし
1
2
3
4
5
?
これを行う正しい方法は何ですか?
(テスト済みfor i in {1..5}; do x=$(i) echo "$x"; done
-bash: i: コマンドが見つかりません
他人)
答え1
要求どおりに質問に答えてください。
なぜ、、、、、を
for i in {1..5}; do x="${i}" echo "$x"; done
出力しないのです1
か?2
3
4
5
その理由は、実行中にジョブが評価される順序に関連しています。このコマンドを見てください
x="${i}" echo "$x"
これは何のためであるか。
- 変数をその値に置き換える
- 変数に一時値を割り当てる
x
- 注文の実行
だからあなたは得ます
x=1 echo ""
(またはx=2 echo ""
等)- このコマンドの実行中は、
x
次の値に設定してください。1
- 注文の実行:
echo ""
x
このコマンドは、値の割り当てとその値の印刷という2つのコマンドと考えることができます。ただし、シェル構文では、作成したコードが完全に合法であるため、シェルはそのような意図なしにコードを実行します。
答え2
次の2つの質問に対する回答をリクエストしました。
現在のコードが予想される出力を生成しない理由の説明を要求しました。
実際に期待される出力を生成するようにコードを書く正しい方法について質問しました。
あなたのコードを見て、なぜこのように書いたのかについての2つの可能な説明を見ることができます。
for ループ構文
最初のケースでは、変数の割り当ての後にセミコロンが欠落していると言いたいと思います。 forループを1行に書き込むには、ループ本文の各コマンドの後にセミコロンを入力する必要があります。この試み:
for i in {1..5}; do x="${i}"; echo "$x"; done
別のオプションは、複数行構文を使用してforループを作成し、セミコロンを改行に置き換えることです。
for i in {1..5}
do
x="${i}"
echo "${x}"
done
セミコロンと改行文字を混在させることもできます。たとえば、次のようになります。
for i in {1..5}; do
x="${i}"; echo "${x}"
done
簡単なコマンド評価
x="$i"
2番目のケースでは、コマンドプロローグの変数割り当て(割り当てなど)が、コマンド本文の変数拡張(${x}
inの拡張など)のecho "${x}"
前に発生すると仮定します。しかしそれは真実ではない。これを確認するにはページをご覧ください。簡単なコマンド拡張Bash マニュアルで、または簡単なコマンドのセクション内部にPOSIX仕様。両方の参照には、次の段落が含まれています。
「単純なコマンド」は、任意の順序で任意の変数割り当ておよびリダイレクトのシーケンスであり、任意にワードおよびリダイレクトが続き、制御演算子によって終了される。
与えられた単純なコマンドを実行する必要がある場合(つまり、AND-ORリストまたはケースステートメントは単純なコマンドをバイパスしません。)コマンドテキストの最初から最後まで、次の拡張、割り当て、およびリダイレクトを実行する必要があります。
手順 2 ではコマンドで変数の拡張が行われますが、手順 1 では変数の割り当てが手順 3 と 4 に保存されることに注意してください。したがって、割り当てが行われるecho "${x}"
まで式は拡張されます。これは、空の出力が表示される理由を説明します。echo ""
x="${i}"
このトピックの詳細については、次の投稿をご覧ください。
答え3
では、Bourne演算子のzsh
3番目の${var::=value}
形式を使用します。ここでの割り当ては無条件です(varが設定されていないかnullの場合には該当しません)。${var=value}
${var:=value}
for i in {1..5}; do echo ${x::=$i}; done
または:
for i ({1..5}) echo ${x::=$i}
存在するbash
:
set -o posix # so the value of x remains after eval returns
for i in {1..5}; do x=$i eval 'echo "$x"'; done
つまり、$x
その拡張を含むコードを評価するときにそれを設定する必要があります。
ここのような10進整数値の場合は、次のこともできます。
for i in {1..5}; do echo "$((x = i))"; done
または、空の文字列に${var:=value}
設定したx
後はいつでもBourne演算子を使用できます。
for i in {1..5}; do x=; echo "${x:=$i}"; done