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

これまでに、なんどか "標準入力・標準出力・標準エラー出力"という言葉 がでてきました。 また、断らずに ">"などを利用してきました。 ここでは、これらがいったいなんなのかを解説したいと思います。

UNIXに限らず普通のコンピュータならば必ず入出力装置があります。 昔は、出力装置はプリンタであったりしたのですが、現在はディスプレイが普 通でしょう。 また、入力装置はキーボードを使うことが普通ですね? 標準入力と標準出力はそれぞれ普通に入出力するための装置に結び付けられて います。

C言語でプログラムを作ったことがある人なら、 getc()で標準入力であるキーボードからの入力が得られ、 putc()で標準出力に出力が出されることを 知っているかもしれませんね 。

では、標準エラー出力とはなんでしょうか? パイプを用いて標準出力と標準入力を結合することを考えてみて下さい。 コマンドの出力に混じって、エラーメッセージが出てしまうと次のコマンドの 入力としてそのエラーメッセージが与えられることになってしまいます。 結局、予期しない結果が出てしまうということがあり得るのです。 そこで、普通の出力である標準出力と、 エラー用の出力である標準エラー出力を作ることになったのです。

後で述べますが、標準エラー出力も標準出力と一緒(もしくは別)に次のコマン ドへの標準入力に結合することも可能です。

標準入出力のファイルへの切り換え

標準入出力のファイルへの切り換えを リダイレクション(redirection)といいます。 ここでは、順にその方法を見て行きましょう。

コマンドの出力をファイルに

まずはじめに、標準出力をファイルに切り換えてみましょう。 コマンドの最後に ">"とファイル名を書けば、 コマンドの出力はそのファイルに入ります。

	       >   who > persons
	       >   cat persons
	      banbara  ttyp2    Jul 13 02:14 (nsg)
	      mutoh    ttyp6    Jul 12 09:58 (sentinel.info.na)
	    
whoの出力が確かに personsというファイルに入っていますね?

標準出力の切り換え方法として、もう一つ ">>"というのがあります。 これは、ファイルが既に存在する場合、 その末尾にコマンドの出力を追加します。 ではやりましょう。

	       >   ls -l >> persons
	       >   cat persons
	      banbara  ttyp2    Jul 13 02:14 (nsg)
	      mutoh    ttyp6    Jul 12 09:58 (sentinel.info.na)
	      -rw-r--r--   1 mutoh    mutoh        87 Jul 13 13:43 persons
	    
確かに、最後の行にls -lの出力が追加されていますね?

コマンドへの入力をファイルから

逆に、コマンドへの入力をファイルから得る場合は、"<"を利用しま す。 やってみましょう。

	       >   cat < persons
	      banbara  ttyp2    Jul 13 02:14 (nsg)
	      mutoh    ttyp6    Jul 12 09:58 (sentinel.info.na)
	      -rw-r--r--   1 mutoh    mutoh        87 Jul 13 13:43 persons
	    
catへの入力として、先程作ったファイルを与えました。 でも、catっていうのは、 もともと引数としてファイル名をとってそれを表示するコマンドでしたね? この動作はどういうことなんでしょうか?

じつは、catは引数が与えられた時には そのファイルを標準出力に表示しようとしますが、 引数が与えられていない時は標準入力から入力を取って 標準出力へ与えられた入力を出力するようになっています。 ちょっと試してみましょう。

	     >   cat
	    This is test of cat.
	    This is test of cat.
	    It works good!!
	    It works good!!
	    C-d
	  

じつは、ファイルの作成で使ったのはこの機能だったわけです。 このように、引数が与えられた時にはそのファイルに対して動作を行ない、 引数が無い時には標準入力から入力を得るコマンドは結構たくさんあります。 探してみて下さい。

標準エラー出力の取り扱い

最後に、標準エラー出力の取り扱いについて説明しましょう。 標準エラー出力の取り扱いは、 /bin/sh/bin/cshと いう2つの代表的なシェルでも記述法が異なります。 ここでは、後者の書き方について説明します。

標準エラー出力と標準出力を 一緒にファイルに落すためには、 ">&"または">>&"を利用します。

	     >   ls -l persons hoge > ls.result
	    ls: hoge: No such file or directory
	     >   ls -l persons hoge >& ls.result
	     >   cat ls.result
	    -rw-r--r--   1 mutoh    mutoh       150 Jul 13 13:49 persons
	    ls: hoge: No such file or directory
	    -rw-r--r--   1 mutoh    mutoh       150 Jul 13 13:49 persons
	  

最初のlsで存在しないファイル hogeを指定しているので、 コマンドからそんなファイルないよというエラーが出ています。 その後で、両方の出力を作ったファイルに追加して表示していますが、 確かにエラーメッセージもファイルの中に入っていますね?

パイプでも、 標準エラー出力を一緒に流すようにできます。 "|&"を使って下さい。

では、標準エラー出力だけを ファイルの中にいれるにはどうしたらいいのでしょうか? 詳しい説明は省略しますが [1]、 以下の例のように記述すれば可能です。

	     >   (ls -l persons hoge > ls.dat) >&ls.err
	     >   cat ls.dat
	    -rw-r--r--   1 mutoh    mutoh       150 Jul 13 13:49 persons
	     >   cat ls.err
	    ls: hoge: No such file or directory
	  

Notes

[1]

実は、シェルの機能で子シェルで実行するというのを使っています。