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

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

スクリプトで次の行を見ました。

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を知っていますが、3and&の用途は何ですか?

答え1

この数字はファイル記述子で、最初の3つ(0から始まる)のみが標準化された意味を持ちます。

0 - stdin
1 - stdout
2 - stderr

したがって、コマンドの各数字はファイル記述子を表します。ファイル記述子をファイルにリダイレクトする>か、別のファイル記述子にリダイレクトできます。>&

3>&1コマンドラインは新しいファイル記述子を作成し、それに1リダイレクトしますSTDOUT。次に、1>&2ファイルディスクリプタ1をリダイレクトSTDERRし、2>&3ファイルディスクリプタ2を3にリダイレクトしますSTDOUT

STDOUTしたがって、デフォルトでおよびを切り替えると、STDERR次の手順が実行されます。

  1. 新しいfd 3を作成し、fd 1を指します。
  2. ファイル記述子1をファイル記述子2にリダイレクトします。 3でファイル記述子を保存しないと、ターゲットが失われます。
  3. ファイル記述子2をファイル記述子3にリダイレクトします。これで、ファイル記述子1とファイル記述子2が置き換えられました。

プログラムがファイルディスクリプタ1に何かを印刷すると、ファイルディスクリプタ2にも印刷され、その逆も同様です。

答え2

交換しstdoutていますstderr

>name出力をファイルにリダイレクトしますname

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

したがって、&ファイル名ではなくファイル記述子を意味することをシェルに伝える必要があります。

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

これはファイル記述子に当てはまり、1デフォルトでに移動するため、新しいシェルで実行しても何も変わりません(現在のファイル記述子番号は3です)。2/dev/ttysomecommand 3>&1 1>&2 2>&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進行したいと思ったかもしれません。stdoutstderr

また、見ることができます注文リダイレクト

答え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"

この例を実行すると、ファイル記述子が並べ替えられ、出力が変更されることがわかります。

関連情報