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