UNIXおよびLINUX系のOSでは、プロセスがファイルの読み書きや作成などをする際に、「ファイルディスクリプタ」という数値(番号)を使用して、対象のファイルにアクセスします。
今回は、プロセスが使用しているファイルディスクリプタの確認方法について学んでいきます。
プロセスIDを確認する
ここでは、WSL(Windows Subsystem for Linux)のUbuntu18.04で確認しています。
まずログインシェルであるbashのプロセスIDを確認します。
> ps aux | grep [b]ash ubuntu 4 0.9 0.0 16924 3680 tty1 S 0:00 0:00 -bash
上記からbashのプロセスIDは4であることが確認できました。
ファイルディスクリプタを確認する
ファイルディスクリプタは"/proc/<process id>/fd/"ディレクトリにその詳細が記載されています。
以下コマンドで確認してみます。
> ls -al /proc/4/fd/ total 0 dr-x------ 2 ubuntu ubuntu 0 Dec 21 00:00 . dr-xr-xr-x 7 ubuntu ubuntu 0 Dec 21 00:00 .. lrwx------ 1 ubuntu ubuntu 0 Dec 21 00:00 0 -> /dev/tty1 lrwx------ 1 ubuntu ubuntu 0 Dec 21 00:00 1 -> /dev/tty1 lrwx------ 1 ubuntu ubuntu 0 Dec 21 00:00 2 -> /dev/tty1 lrwx------ 1 ubuntu ubuntu 0 Dec 21 00:00 255 -> /dev/tty1
上記の0, 1, 2番は、それぞれ「標準入力」、「標準出力」、「標準エラー出力」として予約されているもので、システムの起動時から使用されているものです。
このシステムでは、全て"/dev/tty1"へのシンボリックリンクになっています。
標準出力を変更してみる
入門UNIXシェルプログラミングの「第4章6 execコマンドとリダイレクション」で標準出力を"/dev/null"に変更し、コマンドの実行結果を表示しなくなるサンプルを使って、ファイルディスクリプタの状態を確認してみます。
> exec > /dev/null > ls -al /proc/4/fd/ >&2 total 0 dr-x------ 2 ubuntu ubuntu 0 Dec 21 00:00 . dr-xr-xr-x 7 ubuntu ubuntu 0 Dec 21 00:00 .. lrwx------ 1 ubuntu ubuntu 0 Dec 21 00:00 0 -> /dev/tty1 l-wx------ 1 ubuntu ubuntu 0 Dec 21 00:00 1 -> /dev/null lrwx------ 1 ubuntu ubuntu 0 Dec 21 00:00 2 -> /dev/tty1 lrwx------ 1 ubuntu ubuntu 0 Dec 21 00:00 255 -> /dev/tty1
上記で標準出力を"/dev/null"に捨ててしまっているので、通常のコマンドの実行結果はコンソールに表示されません。
そのため、">&2"で標準出力を標準エラー出力にリダイレクトしてコマンドの実行結果を表示しています。
ファイルディスクリプタの番号1のシンボリックリンクが"/dev/null"に変更されているのが確認できました。
確認後に"exec > /dev/tty1"に戻すのを忘れないようにしましょう。
最後に
今回はファイルディスクリプタの確認方法について学びました。
ネットワークプログラミング等で使うソケットも、このファイルディスクリプタを指定することで、データの送受信を行っています。
特に0, 1, 2番の3つの標準ディスクリプタは重要ですので、覚えておいたほうが良さそうです。