Linuxにはたくさんのコマンドがありますが、その一つ一つは小さな処理をするようにシンプルに設計されています。
一つのコマンドは単純な処理をするという方がわかりやすいですよね?
ですが、複雑な処理をしたい場合もあると思います。
そんな時は、小さな処理を行うコマンドを連携させて大きな処理を作ればいいのです。
ここで紹介する「リダイレクト」と「パイプライン」はコマンドを組み合わせて連携させるための仕組みです。
この記事を読めば、linuxのコマンドを組み合わせて様々な処理をさせることができるようになります。
標準入力と標準出力と標準エラー出力とは?
コマンドの連携の説明をする前に、コマンド間で情報をやりとりする仕組みを知っておく必要があります。
Linuxではcatコマンドなどのコマンドが起動すると、自動的に標準入出力のチャネルが開かれます。
チャネルとはデータが流れる道と思ってください。
入出力チャネルは3つあります。
- 標準入力(stdin)
プログラムの標準的な入力です。 - 標準出力(stdout)
プログラムの標準的な出力です。 - 標準エラー出力(stderr)
プログラムのエラーメッセージを出力するための標準的な出力です。
入力では通常はキーボードが使われますし、出力としてはディスプレイになる場合が多いでしょう。
これらの3つを合わせて標準入出力と呼びます。
プログラム自体は、キーボードからの入力とかディスプレイに出力しているとかいうことは気にしていません。
標準入力から入ってきた情報を処理して、標準出力に出力するということをやっているだけです。
なお、標準入出力を実際にどこに繋ぐかは、ユーザが自由にシェルで制御でできます。
このような仕組みになっているため、コマンドの処理内容を変更することなく、標準入出力先を柔軟に変更することができます。
リダイレクトとは?
標準入出力先を変更する機能をリダイレクトと呼びます。
入力、出力ともにリダイレクトすることが可能です。
標準入力のリダイレクト
catコマンドはファイルをしてしないで実行すると、標準入力待ちの状態になります。
入力待ち状態でキーボードから入力しEnterキーを押すとcatコマンドの処理が実行されます。
catコマンドは「標準入力の内容を入力として読み込み、それを標準出力にそのまま出力する」というコマンドです。
標準出力として出力されたものが二つ目のtestになります。
$ cat
test
test
catコマンドを終了するには「Ctrl + d」を押します。
この例では、キーボードからの入力を標準入力としましたが、次はファイルを標準入力としてcatコマンドを実行してみましょう。
これを入力リダイレクトと呼びます。
リダイレクトをするには「<」を使います。
$ cat < /etc/hostname
testcent
ここでは/etc/hostnameファイルの内容を標準入力に指定してcatコマンドを実行しています。
catコマンドは入力された内容をそのまま標準出力に出力しています。
/etc/hostnameファイルはホスト名が書かれたファイルなのでホスト名が出力されました。
標準出力のリダイレクト
標準出力もリダイレクトの機能により変更できます。
例えば、コマンドの実行結果を画面に表示させるのではなく、ファイルに保存する場合などです。
標準出力をリダイレクトするには「>」を使います。
では、lsコマンドの実行結果をlist.txtというファイルに保存してみましょう。
$ ls -l / > list.txt
こうすると、画面には実行結果が出力されることなく、処理が終了します。
標準出力がリダイレクトされたため、画面に表示されなかったのです。
標準エラー出力
出力チャネルには標準出力に加えて標準エラー出力というのがあります。
標準エラー出力は主にプログラムのエラーメッセージを出力するためのチャネルです。
例えば、catコマンドで存在しないファイルを指定した場合、次のようなエラーメッセージが表示されますが、これは標準エラー出力チャネルから出力されています。
$ cat /test
cat: /test: No such file or directory
この例では、標準エラー出力と同じように画面に表示されるので標準出力なのか標準エラー出力の結果なのかが区別できません。
そこで、標準出力をファイルにリダイレクトするようにしてみましょう。
$ cat /test > stdout.txt
cat: /test: No such file or directory
$ cat stdout.txt
$
こうすると標準エラー出力が画面に表示され、ファイルには何も書き込まれませんでした。
「>」は標準出力をリダイレクトする記号なので標準エラー出力はリダイレクトされません。
なお、標準エラー出力もファイルにリダイレクトすることができます。
標準エラー出力のリダイレクトは「2>」という記号を使います。
標準出力と標準エラー出力をまとめる
標準出力と標準エラー出力の両方を、1つのファイルにまとめてリダイレクトする方法があります。
標準リダイレクトした後ろに「2>&1」と書くと可能です。
$ ls /etc > result.txt 2>&1
このコマンドの意味は、まず標準出力をresult.txtにリダイレクトします。
そして、標準エラー出力を&1にリダイレクトします。
&1は標準出力を指しています。
Linuxの内部では標準入出力が数値として管理されています。
標準入出力と数値を以下の表にまとめます。
入出力チャネル | 数値 |
標準入力 | 0 |
標準出力 | 1 |
標準エラー出力 | 2 |
リダイレクトによるファイルの上書き
「>」で標準出力をリダイレクトする際に、指定したファイル名が既に存在している場合、上書きされてしまいます。
上書きを防ぐには「>>」を指定します。
こうすることで、ファイルは上書かれることなくファイルの末尾に追記する形で出力をリダイレクトすることができます。
リダイレクトまとめ
リダイレクトの記号と内容をまとめます。
記号 | 内容 |
< file | 標準入力をfileに変更する |
> file | 標準出力をfileに変更する |
>> file | 標準出力をfileの末尾に追記する |
2> file | 標準エラー出力をfileに変更する |
2>> file | 標準エラー出力をfileの末尾に追記する |
> file 2>&1 | 標準出力と標準エラー出力をfileに変更する |
パイプラインとは?
複数のコマンドを連携させるには、あるコマンドの結果を別のコマンドに渡してあげる必要があります。
コマンドの標準出力を別のコマンドの標準入力に繋ぐ役割を果たすのがパイプラインです。
例えば、lsコマンドの実行時にファイルが多すぎて表示結果が1ページに収まらない場合があります。
この場合、lsコマンドの標準出力をlessコマンドの標準入力に繋ぎ、lessコマンドの標準出力の結果を得ることができます。
$ ls -l / | less
パイプラインを図で表すと以下のようなイメージになります。
また、パイプラインは何回でも使用できます。
色々なコマンドをパイプラインでつないでいくことで様々な処理を行えるようになっています。
なお、パイプラインは標準出力だけを繋ぐようになっっているので、標準エラー出力もパイプラインで繋ぎたい場合は「2>&1」を使って標準エラー出力のリダイレクトをする必要があります。
Linuxの標準入出力とパイプまとめ
リダイレクトとパイプラインについて解説してきました。
Linuxを使う上で非常に重要な概念なのでしっかりと覚えておきましょう。
シェルスクリプトの作成などでも利用するので理解しておくことが必要です。
コメント