ROUTE 3390

備忘録的な用途で書いていますが、どなたかの役に立つ事があれば嬉しいです。

標準入力と標準出力と標準エラー

プログラムを4年書いてて標準入力とかファイルディスクリプターという言葉が
何を指すのか知らなかった。。

ほんと僕みたいなプログラマーが世界中にどれだけいるんだろう。
心配になってくる。。


まずは「ファイルディスクリプター」の説明です。
これはOSが認識するデバイス達(キーボードやマウス、ディスプレイ、ハードディスクなんかも)と標準入力なんかを結びつけるものです。

内部的にはデバイスに整数値(3から順番に)を割り当てています。ポインタ的な

たとえばこんなプログラムがあったとします。

##############
[1]ファイルAをオープン
[2]色々書き込む
[3]ファイルAをクローズ
##############

このプログラムがファイルA操作しようとするとファイルディスクリプタがファイルAに整数を割り当てます。(仮に3とします)
何故「3」かは後で説明します。

プログラムは割り当てられてた「3」にむかって出力する事で書き込む動作になります。

Perlで書いてみると

open(IN, 'data.txt');
print IN 'Hello, World!';
close(IN);

同じ事を何度も書きますが、INは内部で(3以降の)整数がファイルディスクリプタによって割り当てられています。
その割り当てられたINに対して print(出力)すると、出力先のデバイスがテキストファイルなので「出力=書き込み」になります。

perlではfileno()という関数で割り当てられた整数を取得出来ます。


printって画面に表示させる関数って思ってましたが、違うんです。指定したデバイスへ出力する関数なので、デバイスがディスプレイなら画面へ表示されるだけなのです。

出力先のデバイスがファイルならデータが書き込まれ、キーボードならボタンが勝手に凹み(お師匠の受け売りw)
スピーカーなら発音されます(後半はウソばっかりですが、そんなイメージです。)


さて、ではなぜファイルディスクリプタは3以降の整数を割り当てるのでしょうか。
それは0〜2は予約されている(既に決まっている)のです。

0:標準入力
1:標準出力
2:標準エラー

さぁやっとタイトルのキーワードが出てきました。
でもあとは簡単。

標準というのはデフォルトって認識で結構です。

OSはその時々によってデフォルトの入力先、出力先などを決めています。
例えば下記のように

▼Webサイトへアクセスであれば
標準入力:URL
標準出力:ユーザのブラウザ
標準エラー:Apacheログ
▼Cronであれば
標準入力:shコマンド
標準出力:メール送信
標準エラー:メール送信

こんなCronがあったとしましょう。

0 10 * * * Good_morning.pl 1>/dev/null 2>/dev/null

解説するとGood_morning.pl の標準出力先を/dev/nullに、
標準エラーも/dev/nullに吐き出します。
「/dev/null」というのはゴミ箱みたいなものです。
このように書く事で、プログラムからどんな出力があっても
どんどんゴミ箱に吐かれていき、パッと見た感じ何もアウトプットされません。

ちょっと道を外れますが、下記2行は同じです。

0 10 * * * Good_morning.pl 1>/dev/null 2>/dev/null
0 10 * * * Good_morning.pl 1>/dev/null 2>&1

「2>&1」というのは 2の出力先を1と同じにするという意味になります。

0 10 * * * Good_morning.pl 1>/dev/null

こう書くと標準エラーが出力された場合のみメールが送信されます。



以上で標準入力やらファイルディスクリプタの説明は終わりになりますが、最後におまけです。

ファイルディスクリプタが扱う事の出来る上限値は無限ではありません。
システム全体で利用出来る上限値や、ユーザが使用出来る上限値が細かく決まっています。

サーバーにアクセス出来るユーザ数(プロセス数とか)に限界があるのもそのためです。