Bashでコマンドの前に変数を設定するのが正当な理由は何ですか?

Bashでコマンドの前に変数を設定するのが正当な理由は何ですか?

私は次のようないくつかの答えを見つけました。区切られたテキストファイルを解析しています...次の構造を使用してください。

while IFS=, read xx yy zz;do
    echo $xx $yy $zz
done < input_file

ここでIFS変数はコマンドの前に設定されますread

私は読んでいたバッシュリファレンスしかし、これがなぜ正当なのか理解していません。

頑張った

$ x="once upon" y="a time" echo $x $y

bashコマンドプロンプトからエコーを受け取りません。誰かがこの構文を参照で定義し、IFS変数をこのように設定できるように指示できますか?これは特別なケースですか?それとも他の変数にも同様のことができますか?

答え1

関連情報は以下で確認できます。マニュアルページBASH管理者が提供しました(最後の確認:2020年8月)。シェル構文セクション、単純なコマンド状態(強調追加):

簡単なコマンドはオプションの変数割り当て順序 その後の空間分離 単語とリダイレクト、制御演算子によって終了します。これ最初の単語実行するコマンドを指定し、引数0に渡されます。残りの単語は、呼び出されたコマンドに引数として渡されます。

したがって、希望の変数を渡すことができます。echo変数はシェルで設定されず、コマンドに渡されるため、例は機能しません。殻が膨張し$x$y 今後コマンドを呼び出します。たとえば、次のように動作します。

$ x="once upon" y="a time" bash -c 'echo $x $y'
once upon a time

答え2

定義された変数は、分岐プロセスの環境変数と同じです。

走れば

A="b" echo $A

その後、bashは最初に次に展開され、次に$A実行""されます。

A="b" echo

正しい方法は次のとおりです。

x="once upon" y="a time" bash -c 'echo $x $y'

一重引用符を参照してください。bash -cそうしないと、上記の問題が発生します。

したがって、bash組み込みの「read」コマンドは環境変数でIFSを見つけて見つけるため、ループ例は合法です,

for i in `TEST=test bash -c 'echo $TEST'`
do
  echo "TEST is $TEST and I is $i"
done

印刷するTEST is and I is test

最後に、構文上 for ループには文字列が必要です。それで、バックティックを使ってコマンドに置き換えなければなりませんでした。しかし、whileループにはIFS=, read xx yy zz

答え3

man bash

環境

[...]上記のパラメータで説明されているように、単純なコマンドまたは機能の環境は、パラメータの割り当てを先に追加することで一時的に改善できます。これらのディレクティブは、コマンドで表示される環境にのみ影響します。

変数は変数の割り当て前に拡張されます。明らかな理由で、var=xその逆は本当ですが、そうではvar=$othervarありません。つまり、$x利用可能になる前にあなたのものが必要です。しかし、それは主な問題ではありません。主な問題は、コマンドラインはシェル環境でのみ変更できますが、割り当てはシェル環境の一部ではないことです。

機能が混乱しています。コマンドラインを変更したいのですが、変数定義をコマンド環境に入れます。コマンドライン置換はシェルで行う必要があります。呼び出されるコマンドは明示的にこの環境を使用する必要があります。これが行われるかどうかは、コマンドによって異なります。

この使用法の利点は、シェル環境に影響を与えずに子プロセスの環境を設定できることです。

x="once upon" y="a time" bash -c 'echo $x $y'

予想通り、この場合、2つの機能が組み合わされています。コマンドライン置換は、コールシェルではなくサブプロセスシェルによって実行されます。

答え4

より大きな絵を追求したい」なぜ合法だ」

A:この方法でプログラムを呼び出すか、その呼び出しに対して特定の変数と一緒に変数のみを使用できます。

たとえば、「db_connection」というデータベース接続パラメータがあり、通常はテストデータベース接続名として「test」を渡します。実際にこれをデフォルトに設定することもでき、明示的に渡す必要はありません。しかし、時にはciデータベースを使用したい場合があります。したがって、呼び出されたプログラムで使用される "ci" に引数を渡します。それデータベースパラメータは、すべてのデータベース呼び出しに使用されるデータベースの名前として機能します。次の実行では、メソッドを繰り返さずにプログラムのみを呼び出すと、変数は以前のデフォルト値に戻ります。

関連情報