テキストエディタで/ dev / stdoutを読み取れないのはなぜですか?


9

LinuxでのEverything Is a File TMの学習を始めたばかりで、文字通り/ dev / stdoutから読み取るとどうなるのだろうと思いました。

$ cat /dev/stdout 
^C
$ tail /dev/stdout 
^C

^Cハングした後、プログラムを強制終了します)。

で試すとvim、考えられないメッセージが表示されます。「/ dev / stdout」はファイルではありません。ギャスプ!

では、これらの「ファイル」を読み込もうとすると、ハングアップやエラーメッセージが表示されるのはなぜですか。


1
vimがファイルと見なすものと* nixの「すべてがファイル」(関連商標なし)が意味するものは同じものではありません。たとえば、#1および#2を参照してください。
goldilocks

回答:


11

なぜハングアップするのですか

cat(1)およびから「ハングアップ」が発生しておらずtail(1)、読み取り時にブロックされているだけです。 cat(1)入力を待ち、完全な行が見つかるとすぐに出力します。

$ cat /dev/stdout
foo
foo
bar
bar

ここに入力しましたfooEnterbarEnterCTRL- D

tail(1)入力を待ち、検出できる場合にのみ出力しますEOF

$ tail /dev/stdout
foo
bar
foo
bar

ここでもう一度入力しましたfooEnterbarEnterCTRL- D

またはエラーメッセージ

Vimだけがエラーを表示します。これは、に対して実行 され、ビットが設定されていないことが判明したためです。stat(2)/dev/stdoutS_IFREG

/dev/stdoutファイルですが、通常のファイルではありません。実際、カーネルにはファイルシステムのエントリを与えるためのダンスがいくつかあります。Linuxの場合:

$ ls -l /dev/stdout
lrwxrwxrwx 1 root root 15 May  8 19:42 /dev/stdout -> /proc/self/fd/1

OpenBSDの場合:

$ ls -l /dev/stdout
crw-rw-rw-  1 root  wheel   22,   1 May  7 09:05:03 2015 /dev/stdout

FreeBSDの場合:

$ ls -l /dev/stdout
lrwxr-xr-x  1 root  wheel  4 May  8 21:35 /dev/stdout -> fd/1

$ ls -l /dev/fd/1
crw-rw-rw-  1 root  wheel  0x18 May  8 21:35 /dev/fd/1

5

(ほとんど)すべてがファイルですが、すべてが通常のファイルであるとは限りません。ディレクトリ、ネットワークソケット、シリアルポートなどの特別なファイルでテキストエディターを呼び出すことは意味がありません。

ファイル/dev/stdoutは、UNIXのバリアントに応じて、いくつかのいずれかになります。

  • 「特別な」ファイル、通常はキャラクターデバイス。
  • アクセスするプロセスがこの記述子で開いているファイルを指す「マジック」シンボリックリンク。
  • 上記のいずれかにシンボリックリンク。

いずれの場合も、/dev/stdout類似のファイルを開くと、アプリケーションがファイル記述子1ですでに開いている同じファイルに関連付けられた新しいファイル記述子が作成されます。「標準出力」はファイル記述子1を意味し、このファイル記述子が使用されるのは単なる規則です。出力用—カーネルは気にしません。

端末でプログラムを実行すると、3つの標準記述子(0 =標準入力、1 =標準出力、2 =標準エラー)がすべて端末デバイスで開かれます。そのデバイスから読み取ると、ユーザーが入力した文字が返され、そのデバイスに書き込むと、ターミナルウィンドウにテキストが表示されます。(端末デバイスが与えられた場合、表示される出力を読み取る、または入力をそれに注入する標準的な方法はありません。)

これらの3つのファイル記述子は同じファイルに接続されているためcat /dev/stdout、を実行すると、cat /dev/stdinor とまったくcat /dev/stderr同じ動作をしますcat。ターミナルから読み取るように指示します。それは何cat引数なしであまりにも行います。

を実行した場合はcat /dev/stdout >foo/dev/stdoutファイルを参照します。fooこのコマンドはと同等cat foo >fooです。cat実装に応じて、エラーが発生するか(GNUバージョンでは「入力ファイルは出力ファイル」と表示されます)、foo空のファイルから読み取るため(何も>foo切り捨てない)、何もしない場合があります。のバージョンではcat、この特別なケースが検出されfooず、が空でない場合、cat /dev/stdout >>fooまたは同等cat foo >>fooのものは、ファイルのコンテンツをそれ自体に無期限に追加します。

を実行vim /dev/stdoutすると、ターミナルの編集方法がわからないため、文句を言われます(意味がありません)。


2

catそしてtail、オプションのコンテンツの後にファイルの終わりが続くのを探しています。/dev/stdout開いたままなのでcattail見続けるだけです。

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