&6と/ dev / fd / 6の違いは何ですか?


11

ファイル記述子6から読み取るには、<&6or </dev/fd/6(別名/proc/self/fd/6)を使用できます。通常、どちらも同じように機能します。しかし、そのファイル記述子がたまたまソケットである場合、奇妙なことが起こります。例えば:

$ bash -c 'ls -l /dev/fd/6;cat /dev/fd/6' 6</dev/tcp/localhost/12345
lrwx------ 1 michas michas 64 Jan 10 19:50 /dev/fd/6 -> socket:[315010]
cat: /dev/fd/6: No such device or address

ここでlsは、記述子が実際に存在することを示しています。ただし、この方法ではデータにアクセスできません。cat <&6代わりに使用すると、すべてが再びうまく機能します。

ファイル記述子にアクセスする両方の方法の違いは何ですか?

変数で番号が指定されている場合、記述子にアクセスするための良い方法はありますか?(</dev/fd/$fd動作しますが、<&$fd動作しません。)

(上記の状況はLinuxでは観察できますが、OpenBSDでは観察できません。-そのファイル記述子はそこで通常の文字デバイスであるようです。)


1
これは複製されたものです
cuonglm

2
ありがとう。関連していますが、実際には重複していません。
michas

回答:


5

これ/dev/fd/は、ソケットを表すエントリからの読み取りがLinuxに実装されていないためです。あなたはここで推論に関するかなり良い記事を見つけることができます。だからあなたstatはリンクを呼び出すことができます、そしてそれがlsでそれを見る理由ですが、アクセスは故意に拒否されます。

次に、第2部について-なぜ機能するのbash -c 'ls -l /dev/fd/6; cat <&6' 6</dev/tcp/localhost/12345ですか?これは、ソケットが/procファイルシステムではなく、ソケット/ファイルAPIを使用して読み取られるためです。これは私が観察していることです:

  1. bash 端末で実行中のインスタンスはfd 6でソケットを作成します。
  2. 児童bashが実行され、呼び出しdup2(6, 0)など、あなたのソケットを取り付けるために、catS」stdin
  3. 場合はdup2呼び出しが失敗しなかった、猫から読み取りますstdin

あなたはそれを再現して観察することができます:

netcat -lp 12345    # in another terminal session (GNU netcat)
strace -f -e trace=open,read,write,dup2 bash -c 'ls -l /dev/fd/6; cat <&6' \
 6</dev/tcp/localhost/12345

bashなぜ子プロセスがfd 6ファイル記述子にアクセスできるのか疑問に思っている場合-ファイル記述子が存続しforkで閉じるようにマークされていない場合exec、それらもそこで閉じられません。


3

あなたの直接の質問に答えるために、「違いは何ですか?」:

からリダイレクトする<&6と、シェルはdup2()システムコールを使用してファイル記述子を複製します。からリダイレクトしようとすると</dev/fd/6、が使用されますopen()

カーネルはのopen()ソケットをサポートしていません/dev/fd。それらは、装飾情報のみのディレクトリにあります。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.