スクリプトで次の行を見ました:
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
と は何のために使用される&
のでしょうか?
答え1
数字はファイル記述子であり、最初の 3 つ (0 から始まる) のみが標準化された意味を持ちます。
0 - stdin
1 - stdout
2 - stderr
コマンド内のこれらの数字はそれぞれファイル記述子を参照します。ファイル記述子をファイルにリダイレクトする>
か、別のファイル記述子にリダイレクトすることができます。>&
3>&1
コマンドラインの は新しいファイル記述子を作成し、 にリダイレクトします。1
次にSTDOUT
、 は1>&2
ファイル記述子 1 を にリダイレクトしSTDERR
、2>&3
ファイル記述子 2 を 3 にリダイレクトしますSTDOUT
。
つまり、基本的には、STDOUT
と を切り替えたことSTDERR
になります。手順は次のとおりです。
- 新しいfd 3を作成し、それをfd 1にポイントします。
- ファイル記述子 1 をファイル記述子 2 にリダイレクトします。ファイル記述子を 3 に保存していなければ、ターゲットは失われます。
- ファイル記述子 2 をファイル記述子 3 にリダイレクトします。これで、ファイル記述子 1 と 2 が入れ替わります。
これで、プログラムがファイル記述子 1 に何かを印刷すると、ファイル記述子 2 にも印刷され、その逆も同様になります。
答え2
スワッピングstdout
とstderr
。
>name
出力をファイルにリダイレクトすることを意味します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
。そのマニュアルページ、 なるほど
Some widgets, e.g., checklist, will write text to dialog's output.
Normally that is the standard error
おそらくスクリプトを書いた人は、何らかの理由で のdialog
出力をstdout
ではなくに送信したいのでしょう。stderr
答え3
スクリプト作成者は fd 3 を次のように定義しました。
exec 3<> File.txt
「File.txt」を開き、fd 3 を割り当てます。最大ファイル記述子: 255
read -n 4 <&3
4文字のみ読み取ります。
echo -n . >&3
そこに小数点を書いてください。
exec 3>&-
fd 3 を閉じます。
cat File.txt
==> 1234.67890
答え4
以下の例から、ファイル記述子と「3> & 1 1> & 2 2> & 3」コマンドの目的を理解しました。
#!/bin/bash
#it's normal case fd environment
echo test 1> afile.txt
echo "Test no 1"
cat afile.txt
echo "Test no 1"
echo test 2> afile.txt
echo "Test no 2"
cat afile.txt
echo "Test no 2"
echo test 1> afile.txt
echo "Test no 3"
cat afile.txt
echo "Test no 3"
echo test 2> afile.txt
echo "Test no 4"
cat afile.txt
echo "Test no 4"
echo > afile.txt
echo "------------------------------------------------------------------------"
#it's relocate filedescriptor and cause not problem, and cause error(std error)
var=
var=$(echo test 3>&1 1>&2 2>&3)
echo "Test no 5"
#cat afile.txt
echo $var
echo "Test no 5"
var=
var=$(echo test 3>&1 1>&2 2>&3)
echo "Test no 6"
#cat afile.txt
echo $var
echo "Test no 6"
var=
var=$(echo test 3>&1 1>&2 2>&3)
echo "Test no 7"
#cat afile.txt
echo $var
echo "Test no 7"
var=
var=$(echo test 3>&1 1>&2 2>&3)
echo "Test no 8"
#cat afile.txt
echo $var
echo "Test no 8"
この例を実行すると、ファイル記述子が再配置され、出力が変化することがわかります。