web-dev-qa-db-ja.com

ファイル記述子の読み取り

fileという名前のファイルの内容

testing 1
testing 2

テストされたコマンド

exec 3<> ./tmp
cat file 1>&3 3>&1

何も出力しません。どうして?

私は自分のコマンドを次のように読みます

catfileコンテンツ、次にSTDOUTを読み取ってファイル記述子3に渡し、ファイル記述子3からコンテンツを取得してコンテンツをSTDOUT

コマンドを間違って読んでいますか?

コマンドを理解してfileの出力を取得するには、コマンドをどのように読みますか?


あなたの答えステファンを理解した後、私は次のコマンドを試しました

cat file 1>&3 3> ofile

fd 3のコンテンツ(fd 1、つまりSTDOUTからコンテンツを取得)をofileに書き込みませんでした。

しかし、私は次のコマンドを試しました

cat file 1>&3 && cat <3

fd 3の内容をSTDOUTに出力します。

Fd3にfd1の内容があるのに、なぜfd3がofileに書き込まなかったのですか?


Stéphane、コマンドJesse_bは以下のコメントで言及されています。

cat file 3> ofile 1>&3 

動作し、fileのコンテンツをofileに書き込みますが、コマンド

cat file 1>&3 3> ofile

前に述べたように、ofileへの書き込みに失敗します。

1>&3の最後と最初の3> ofileの配置は、これら2つのコマンドの出力にどのように影響しましたか?

4
GypsyCosmonaut

_cmd x>&y_は言う:「fd xをfd yがリダイレクトされるリソースにリダイレクトする」

だから:

_cat 1>&3 3>&1
_

catのfd 1(stdout)は、fd 3で開いているのと同じリソース、つまり、読み取りと書き込みモードで_./tmp_ openに移動する必要があると言っています。次に、fd3をfd1で開いているのと同じリソースに移動します。これは、_./tmp_にしたばかりです。

したがって、catは、fds 1と3の両方が_./tmp_にリダイレクトされた状態で開始されます。 catはそのfd3に対して何もしませんが、catのfd3を好きなものにリダイレクトできます。効果はありません。

ただし、fileの内容はfd 1に書き込まれるため、_./tmp_の先頭に書き込まれたfileの内容を確認できます。

_cat file_は、fileのコンテンツを1回だけ、1つのfdにのみ書き込みます。 fileの内容を2つの異なるfdsに2回書き込むものが必要な場合は、代わりにteeが必要です。

_< file tee ./tmp
_

teeは、fd 0(ここでは読み取り専用モードで開くfileにリダイレクトされます)から読み取ったものを_./tmp_(切り捨てを伴う書き込み専用モードで開く)とfd 1(stdout)の両方に書き込みます。

teeに_./tmp_を_-a_でappendモードで開くように指示することは可能ですが、切り捨てずに_./tmp_を読み取り+書き込みモードで開くように指示することはできません_3<>_のように。

そのためには、次のものが必要です。

_< file tee /dev/fd/3 3<> ./tmp
_

これはLinux以外で機能するか、zshとその組み込みのティー機能を使用することになります。

_cat < file 3<> ./tmp >&1 >&3 3>&-
_

Fd 1が2回リダイレクトされると、zshオプションが有効になっている場合(デフォルトでオン)、mulltiosは、出力を両方の宛先に転送するために内部teeを実行します(catの出力を読み取り、両方の宛先に書き込む内部プロセスを実行することにより) 。

Fd 3の一時的な使用は、次の問題を回避することです。

_cat < file >&1 1<> ./tmp
_

zshは、_zsh: file mode mismatch on fd 1_からreadを実行したいと想定しているため、_./tmp_に文句を言います。

5