2.5 パイプ

2.5.1 準備 -- 一時ファイルを使った複数コマンド処理

who コマンドを使うと,同じコンピュータを使っているユーザーの一覧が得られます。 who と wc を使ってコンピュータにログインしているユーザーの人数を調べてみましょう。

  1. まず,who コマンドを引数なしで実行し,どんな出力が得られるかを確認してください。

    一行につき 1 ユーザーの情報が出力されますね。 who の出力から行数を求めれば,ログインしている延べユーザー数がわかります。

  2. who コマンドの出力を,リダイレクトを使ってファイル user に保存します。
    who > user
    \includegraphics*{who_user.eps}
    cat コマンド等で user の中身を確認してください。

  3. wc コマンドにオプション -l (エル) を指定して,ファイル user の行数を調べます。 ここでは wc にファイル名の引数を与えずに,wc の標準入力から user を読み込むこととします。
    wc -l < user
    \includegraphics*{wc_user.eps}
    ユーザー数がわかりましたね。

  4. ファイル user は不要になりましたので,削除してください。
    rm user

2.5.2 コマンドの連結 -- パイプ

あるコマンドの標準出力を,ファイルではなく,別のコマンドの標準入力に直接接続することが可能です。 その操作をパイプと呼びます。 パイプは,コマンド行において,一連のコマンドを「縦棒 (|)」で区切って記述することによって行います。 パイプによって連結された一連のコマンドをパイプライン (pipeline) と言います。

なお,コマンドの標準出力と標準エラー出力の両方を,続くコマンドの標準入力に接続するには,tcsh の場合,| の代わりに |& とします。

例1: who と wc でログイン中のユーザー数を得る

前節の操作をパイプを使って行います。
who | wc -l
この状況を図示したのが次の図です。 wc は,ファイル名の引数が無いときに,標準入力 (stdin) から読み込みをするのでしたね。 パイプと共に wc を実行する場合, wc は標準入力 (stdin) から入力を受け取る必要がありますので,wc の引数にファイル名を指定してはいけないことに注意しましょう。
\includegraphics*{pipe_who_wc.eps}

例2: ls の出力を more で見る

more はページャ (pager) という種類のコマンドの一つで, 画面に収まらないファイルの内容を 1 ページずつ見るために使われます7。 ここでは,/etc ディレクトリ内の全ファイルの詳細情報を ls コマンドで出力し,これをパイプと more で表示します。
ls -l /etc | more
more コマンドは,more year のように引数にファイル名が与えられれば, そのファイル用の入り口を作って読み込みますが, ファイル名を与えずにリダイレクトやパイプと共に用いると,標準入力から入力を受け取ります。 次の図では ls の引数 (-l /etc) の記述は省略しています。
\includegraphics*{pipe}
動作の概要は以下のとおりです。
  1. ls が実行結果を標準出力に出力します。

    ls の標準出力をパイプによって more の標準入力に接続しているので,ls の実行結果は画面には出力されません。

  2. more が ls の実行結果を標準入力から受け取り,標準出力を通じて画面に表示します。
    1. more は一画面分以上の入力を受け取ると対話的な動作をしますので,一画面分の表示を終えたところで表示を止め,ユーザーからの命令を待っている状態になります。
    2. ユーザーがスペースキー等を押して全ページを表示させ終えるか,q 等を押すことで more を終了させると, パイプライン全体が終了し,プロンプトが表示されます。

2.5.3 コマンドの多段連結

command1 が標準出力 (stdout) に結果を出力するコマンドであり,command2command3 が標準入力 (stdin) から入力を読み取って結果を標準出力 (stdout) に出力するコマンドならば,
command1 | command2 | command3
により,次の図に示す多段のパイプが可能です。 これにより,command1 の出力が command2 で処理され,さらに command3 で処理されます。


\includegraphics*{multi_pipe}
なお,これまでと同様に,パイプラインの中の各コマンドには引数を与えることもできます。 また,4つ以上のコマンドをパイプすることもできますし,その出力をリダイレクトでファイルに保存することも可能です。

command2command3 のように,標準入力と標準出力を使った入出力が可能なコマンドをフィルタ (filter) といいます。 フィルタはパイプラインの中で利用できるコマンドです。 これまでに紹介したコマンドでは cat と wc はフィルタです。