プログラムの入出力をつなぐ
プログラムがデータを読み書きする接続先を、画面、ファイル、別のプログラムへ切り替えます。
このレッスンのメニュー
ターミナルでプログラムを起動すると、結果は通常、同じ画面へ表示されます。 これは、プログラムの出力先をシェルがターミナルへ接続してから起動するためです。 接続先をファイルや別のプログラムへ変えると、結果の保存や受け渡しができます。
普通の結果とエラーを見る
printfは、指定したテキストを出力します。
printf 'hello\n'
hello
次のlsには、存在しない場所を指定します。
ls /this-path-does-not-exist
ls: cannot access '/this-path-does-not-exist': No such file or directory
どちらの出力もターミナルへ表示されますが、プログラムは普通の結果とエラーを別々の接続先へ書き出しています。 普通の結果だけをファイルへ保存し、エラーは画面で読む、といった使い分けができます。
プログラムが使う三つの入出力
Linux上でプログラムを起動するときは、通常、データを読み込む接続先が一つ、データを書き出す接続先が二つ用意されます。
| 名前 | 役割 |
|---|---|
| 標準入力(stdin) | プログラムが処理するデータを読み込む |
| 標準出力(stdout) | 普通の結果を書き出す |
| 標準エラー出力(stderr) | エラーや診断情報を書き出す |
シェルはプログラムを起動するとき、三つの接続先をどこへつなぐか決めます。 何も指定しない場合は、標準入力をターミナルから受け取り、二つの出力をターミナルへ表示します。
ここでいう入力と出力は、プログラムがデータを読み書きするための接続です。 このページの例では、データとしてテキストを扱います。 標準ではターミナルにつながり、シェルの指定によってファイルや別のプログラムにもつなげられます。
ファイル名を渡す方法と、データを渡す方法
次の例では、grepへ検索する語とファイル名を引数として渡します。
grep localhost /etc/hosts
grepは、引数で指定されたファイルを自分で開いて読みます。
次の例では、ファイル名を渡さず、検索する語だけを引数にします。
grep localhost
この状態でgrepは標準入力からデータが届くのを待ちます。
127.0.0.1 localhostと入力すると、その行が結果として表示されます。
手入力を終えるにはCtrl-Dを押して、入力が終わったことをgrepへ伝えます。
引数は「何をするか、どのファイルを使うか」という指定です。 標準入力は、処理するデータそのものを読み込む接続先です。
標準出力をファイルへ保存する
シェルへ>を書くと、標準出力の行き先をファイルへ変えます。
printf '200 OK\n500 ERROR\n404 ERROR\n' > /tmp/access-sample.log
cat /tmp/access-sample.log
一行目では、printfが返した三行をシェルが/tmp/access-sample.logへ書き込みます。
>は同名のファイルを上書きし、>>は末尾へ追加します。
実行中のプログラムは、開いているファイルや入出力の接続を小さな整数で見分けます。
この番号をファイルディスクリプターと呼びます。
プログラムの起動時には、標準入力に0、標準出力に1、標準エラー出力に2が割り当てられています。
標準エラー出力をファイルへ保存するときは、標準エラー出力の番号を付けて2>と書きます。
ls /this-path-does-not-exist 2> /tmp/ls-error.log
cat /tmp/ls-error.log
>では省略された1、2>では明記された2の行き先を変えます。
標準出力を別のプログラムへ渡す
縦線の|をパイプと呼びます。
シェルは左右のプログラムを起動し、左の標準出力を右の標準入力へつなぎます。
cat /tmp/access-sample.log | grep ERROR
この例は次の順に進みます。
catがファイルを読み、内容を標準出力へ返す- シェルが
catの標準出力をgrepの標準入力へつなぐ grepがERRORを含む行を標準出力へ返す- シェルが
grepの標準出力をターミナルへ表示する
パイプが次のプログラムへ渡すのは、標準出力へ書き出されたデータです。 標準エラー出力は、接続先を別に指定していれば、その接続先へ進みます。
よく組み合わせるプログラムには、次のものがあります。
| プログラム | 返す内容 |
|---|---|
cat | ファイルの内容 |
less | 一画面ずつ読める表示 |
head | 先頭の数行 |
tail | 末尾の数行 |
grep | 条件に合う行 |
wc -l | 受け取った行の数 |
エラーの行を数える
次の各行を実行する前に、各プログラムの結果がどこへ表示または保存されるかを予想します。
cat /tmp/access-sample.log
grep ERROR /tmp/access-sample.log
grep ERROR /tmp/access-sample.log | wc -l
grep NOT_FOUND /tmp/access-sample.log | wc -l
三行目では、grepが返した二行をwcが受け取り、行数の2を返します。
四行目では、grepが返す行がないため、wcは0を返します。
最後に、左のプログラムが何を返し、右のプログラムが何を受け取ったかを自分の言葉で説明します。
このレッスンは完了
このページで扱った流れを確認したら、次の内容へ進みます。