Linuxコマンドラインに関する本を読んでいますが、著者はリダイレクト操作に使用される矢印記号に関するbashマニュアルの規則に従わないようです。つまり、<
記述子が入力記述子であるか出力記述子であるかに関係なく、常に左矢印を使用してファイル記述子をコピーして閉じます。
例は次のとおりです。
exec 3<&0 4<&1 #shouldn't be 4>&1 ?
#...
exec 3<&- 4<&- #shouldn't be 4>&- ?
Bashのマニュアルページはこの点についてあいまいです。ファイル記述子をコピー/クローズして移動する構文は次のとおりです。
#Duplicating and closing (in case word expands to -):
[n]<&word
[n]>&word
#Moving:
[n]<&digit-
[n]>&digit-
明示的に提供していない場合にのみ、そのフォームを交換してn
使用できることを意味しますか?
答え1
どちらも同じことを4>&1
するので重要ではありません。ある fd を別の fd にコピーするシステムコールです。コピーされたfdは、元のfdのI / O方向を自動的に継承します。 (vsと同じで、両方で解決され、その後に続きます)。4<&1
dup2(1, 4)
4>&-
4<&-
close(4)
4>&1-
dup2(1, 4)
close(1)
ただし、4<&1
何らかの理由でfd 1が明示的に読み取り用に開かれていない限り(より混乱する可能性がある)、構文は混乱します。したがって、私の考えではこの構文を避けるべきです。
重複した内容はfd
同じように共有されます。ファイル説明を開くこれは、ファイルが同じオフセット(対応するファイルタイプの場合)と同じ関連付けフラグ(I / Oリダイレクト/オープンモード、O_APPENDなど)を共有することを意味します。
Linuxには他の方法があります。コピーa fd
(実際には重複ではない)を作成し、新しい項目を作成します。ファイル説明を開く同じリソースに対するものですが、フラグが異なる場合があります。
exec 3> /dev/fd/4
dup2(4, 3)
Solaris およびおそらく他のほとんどの Unices では、これは fd 4 が指す同じリソースを最初から開く Linux とほぼ同じです。
これは重要な違いです。たとえば、通常のファイルの場合、fd 3のオフセットは0(ファイルの開始)であり、ファイルは切り捨てられます(これがLinuxではtee -a /dev/stderr
fd 3の代わりに作成する必要がある理由ですtee /dev/stderr
)。
そしてI / Oモードは異なる場合があります。
興味深いことに、fd 4がパイプの読み取り端を指す場合、fd 3は書き込み終了を指します(次のように/dev/fd/3
動作します)。名前付きパイプ):
$ echo a+a | { echo a-a > /dev/fd/0; tr a b; }
b+b
b-b
$ echo a+a | { echo a-a >&0; tr a b; }
bash: echo: write error: Bad file descriptor
b+b