図解:標準入力、標準出力、標準エラー出力、パイプとは ?

home 一覧 掲示板 リンク 検索方法



標準入力、標準出力とは何か?
標準出力をファイルに繋ぐ---ファイルに書き出す作業
標準出力を他のコマンドの標準入力に繋ぐ--パイプ機能
「>」だけじゃなく「<」もある
知らないと危険?---「>」と「>>」の決定的な違い
標準エラー出力とは?
ヒアドキュメント
※書いてあることの保障はしません。

標準入力、標準出力とは何か?

echoというコマンドは、どのUNIX/Linuxの教科書にも載っているけど、なんて使えなさそうなコマンドだと、私は最初の頃思っていました。しかし、このechoこそ、UNIX/Linuxの入出力を知るのに持って来いなのです。例えば、
echo 'Hello'
と打ってみましょう。
Hello 
とかえってくるはずです。なんだ、たいしたこと無いと思うかも知れません。このechoというコマンドは、標準入力を標準出力に返すという単純な命令をこなします。これを図示すると、こんな感じになります。

この図では、端末からechoコマンドという家の「標準入力」という名前の入口にHelloという文字が入っていって、「標準出力」という出口が端末に繋がっていて、Helloという文字が端末に帰ってくる様子を表わしています。まずはコマンドには「標準入力」と「標準出力」という二つの入口と出口があることを覚えて下さい。
コマンドによって、家の中で行なう動作は異なります。例えば
echoは標準入力をそのまま標準出力に流します。
catは標準入力で与えられたファイル名の中身を標準出力に流します。標準入力が複数ある場合、これらのファイルの中身を結合して標準出力に流します。
例題として、revcolrmnltacなどが標準入力に対して、何をして標準出力から出すかを考えてみましょう。

標準出力をファイルに繋ぐ---ファイルに書き出す作業

なにもしていない状態では、標準出力は端末に繋がっていて、何も端末に書き出されました。次にやってみるのは、標準出力を端末でなくてファイルに繋ぎ替える、ということをします。図のイメージでいうと、こんな感じになります。

さて、これを実現してくれるのが > 記号です。
echo 'Hello' > hoge.txt 
この > 記号が標準出力の繋がっている先をhoge.txtに繋ぎかえました。このことをリダイレクトする、といいます。これで、hoge.txtのなかには、
Hello
という感じに標準入力から入った「Hello」がそのまま書かれていると思います。

標準出力を他のコマンドの標準入力に繋ぐ--パイプ機能

上では、標準出力をファイルに繋いで、ファイルに書き出しました。では、標準出力を他のコマンドの標準入力に繋ぐにはどうすれば良いのでしょうか? これを図示すると、

となります。この「パイプ」と書かれている所の記号が | です。このパイプが標準出力と標準入力を繋いでいます。
では具体的な例として、echoと「o」を「!」に変えて標準出力に出すコマンド、sed "s/o/\!/"を用いた
echo 'Hello' | sed "s/o/\!/"
という場合を考えてみましょう。これは、Helloという文字をechoの標準入力に流し、echoがそのまま標準出力へながし、それがパイプを伝って、繋げられたsedの標準入力へ入れられoが!に変換されて、標準出力へ出され、端末へ帰ってくるという道筋を通っています。先ほどの図に書きこむと以下のようになります。

「>」だけじゃなく「<」もある

標準出力を繋ぎかえる(リダイレクト)する「>」だけでなく標準入力を繋ぎかえることもできます。例えば
echo < ファイル
のように<をつかいます。これを図示すると、

のようになります。普通は、コマンドの直後が標準入力になっているので使うことはあまりありませんが。

知らないと危険?---「>」と「>>」の決定的な違い

標準出力、標準入力と少し難しい話がつづいたので閑話休題。といっても、この知識がないと折角のファイルを失ってしまうかもというくらい重要な話です。まず次のコマンドを見て下さい。
echo 'I LOVE YOU !' > loveletter.txt
echo 'But, I must go.' > loveletter.txt
echo 'Please forget me.' > loveletter.txt
loveletter.txtには何が書かれているでしょうか? そうです。
Please forget me.
と書いてあるのです。このように > はファイルを上書きをしてしまいます。これをちゃんと追記したい場合には、 >> を使います。
echo 'I LOVE YOU !' > loveletter.txt
echo 'But, I must go.' >> loveletter.txt
echo 'Please forget me.' >> loveletter.txt
これで、
cat loveletter.txt
I LOVE YOU !
But, I must go.
Please forget me.
となります。まあ、ラブレターぐらいなら良いですが、システムファイルを間違って上書きしてしまったり、徹夜で作ったプログラムを誤って上書きしてしまったりしたら、涙ものです。また、>によるファイルの上書きを禁止することもできます。

標準エラー出力とは?

コマンドには標準入力と標準出力という入口と出口があると書きましたが、実は、もう一つ裏の出口があります。それが標準エラー出力です。標準エラー出力は、標準エラーを出力するところです。普段は標準出力と同様に端末に繋がっています。

この標準エラー出力をファイルにリダイレクトするには、
BashなどB-shell系の場合、
コマンド 2> ファイル名
コマンド 2>> ファイル名
のように(上が上書き、下が追記)、tcshなどのC-shell系では
( コマンド > /dev/null ) >& test
のようにします。
このように標準エラーは通常、標準エラー出力から出力されるので、>を使ったリダイレクトではファイルに書きこまれず、端末にそのまま表示されます。 そこで、標準エラーも標準出力もファイルに書きこむには、>&を用います。
コマンド >& ファイル名
また、標準エラーと標準出力を別のファイルに書きこみたいときは、
Bashなど、B-shell系の場合、
コマンド 1> ファイル 2> 別のファイル
のように、tcshなどC-shell系の場合、
( コマンド > ファイル) >& 別のファイル
のようにします。これでファイルに標準出力、別のファイルにエラーが書きこまれます。

ヒアドキュメント

最後に端末から打った文字をそのままファイルに書く方法を紹介します。この方法はヒアドキュメントと呼ばれます。そのしくみはともかく次の例を見て下さい。
cat << EOF > ファイル
このように打つと、端末に
>
と出るはずです。ここに次々と文字を打っていき、最後にEOFと打つと終るはずです。
>hoge
>hoge
>hoge
>EOF
さて、
cat ファイル
とファイルの中を見てみると
hoge
hoge
hoge
とちゃんと書きこまれているはずです。