スクリプトで「3>&1 1>&2 2>&3」は何をしますか?


69

スクリプトでこの行を見ました:

DEVICE=`dialog --inputbox "Festplatten-Laufzeit auslesen. Gebe Sie das 
gewünschte Device an: " 0 70 "" 3>&1 1>&2 2>&3`

とは

3>&1 1>&2 2>&3

やってる?私は1 = stdoutと2 = stderrを知っていますが、何3&ためですか?


回答:


77

番号はファイル記述子であり、最初の3つ(ゼロから始まる)のみが標準化された意味を持ちます。

0 - stdin
1 - stdout
2 - stderr

したがって、コマンド内のこれらの番号はそれぞれファイル記述子を参照します。ファイル記述子をファイルに>リダイレクトするか、別のファイル記述子にリダイレクトすることができます>&

3>&1あなたのコマンドラインでは、新しいファイル・ディスクリプタを作成し、それにリダイレクトされます1されていますSTDOUT。今すぐ1>&2にファイルディスクリプタ1をリダイレクトするSTDERRと、2>&3ある3へのファイルディスクリプタ2をリダイレクトしますSTDOUT

だから基本的にあなたが切り替えSTDOUTSTDERR、これらはステップです:

  1. 新しいfd 3を作成し、それをfd 1に向けます
  2. ファイル記述子1をファイル記述子2にリダイレクトします。3でファイル記述子を保存しなかった場合、ターゲットは失われます。
  3. ファイル記述子2をファイル記述子3にリダイレクトします。ファイル記述子1と2が切り替えられます。

ここで、プログラムがファイル記述子1に何かを出力すると、ファイル記述子2に出力され、その逆も同様です。


「コマンドラインの3>&1は、新しいファイル記述子を作成し、STDOUTである1にリダイレクトします」と言いました。しかし、1はSTDINを意味しませんか?
sofs1

19

スワッピングstdoutstderrです。

>name出力をfileにリダイレクトすることを意味しますname

>&number出力をファイル記述子にリダイレクトすることを意味しますnumber

そのため&、シェルにファイル名ではなくファイル記述子を意味するように指示する必要があります。

ファイル記述子は、すでに開いているファイルを参照する番号です。標準のものは0、標準入力、1標準出力、または2標準エラー用です。また、他の番号を使用することもできます。これにより、で新しい変数を作成するときと同じように、新しいファイル記述子が作成されvar=valueます。

デフォルトでは、ファイル記述子1との両方に2移動する/dev/ttyためsomecommand 3>&1 1>&2 2>&3、新しいシェルで実行しても何も変わりません(ファイル記述子番号が3になった場合を除く)。

ただし、スクリプトのどこかでexecを使用してリダイレクトをexec 2>error.log実行する場合(例)、またはリダイレクトを含むコマンドラインでスクリプトを実行する場合(例./thescript 2>error.log:)、stdoutとstderrの交換は何かを行います。

特定のケースでは、stdoutとstderrを交換しているコマンドはdialogです。そのmanページを見ると、

Some widgets, e.g., checklist, will write text to dialog's output.
Normally that is the standard error

おそらく、スクリプトを書いた人は、何らかの理由での代わりにdialogの出力を望んでいます。stdoutstderr

リダイレクトの順序も参照してください


弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.