Linuxでは、通常使う入出力に「標準入力」と「標準出力」という名前を付け、多くのコマンドがこれらを利用してデータの受け渡しをしています。通常は、標準入力がキーボート、標準出力は画面に設定されています。
これらをファイルに切り替えることをリダイレクトといいます。
リダイレクトという機能を使うと、コマンドの結果をファイルに保存したり、普段はキーボードから入力しているものをファイルから読み込むようにしたりできます。
リダイレクトはシェルによって提供されている機能で、コマンド共通で使えます。シェルスクリプトを記述していく上で、必ず知っておかないといけない機能です。
リダイレクトの使い方
リダイレクトは「<」や「>」の記号を使って指定します。リダイレクトには、主に次の3種類の使い方があります。
これらの指定をコマンドの後ろにつけておくことで、リダイレクトを指定してコマンドを実行することができます。
< ファイル名 | ファイルから入力 |
---|---|
> ファイル名 | ファイルに出力 |
>> ファイル名 | ファイルの最後に追加 |
「標準エラー出力」もある
コマンドの出力には、標準出力のほかに標準エラー出力があり、エラーメッセージやヘルプメッセージの表示などで利用されています。通常は標準出力に混ざって標準エラー出力が表示されます。
標準エラー出力をリダイレクトするには、「>」の直前に「2」という数字を付けます。標準出力の場合は「1」ですが、この数字は省略できます。
$ cp a b 2> out
入力と出力に同じファイルを指定してはいけない
次のようなコマンドを入力するとどうなるでしょう?
$ tr a-z A-Z < data > data
はじめにdataファイルの内容を読み込み、コマンドの結果をdataファイルに上書きするように思えます。ただ、実際には、ファイルの内容は消えてしまいます。
これは、リダイレクトプロセスが生成されるとき、入力用ファイルと出力用ファイルを同時に開いて処理するためです。
つまり、同じコマンドに対して、入力と出力に同じファイルを指定することはできません。
リダイレクトを使ったシェルスクリプトサンプル
リダイレクトを使った簡単なシェルスクリプトを作成してみましょう。
標準入力のリダイレクト
標準入力のリダイレクトを使ったサンプルを作成します。まず、入力用のファイルを作成します。
$ vi infile hello
続いて、スクリプトファイルを作成します。
$ vi sample06.sh #!/bin/sh tr a-z A-Z < infile
「tr a-z A-Z」は、標準入力から入力したアルファベットの小文字を大文字に変換するコマンドとオプションです。
「infile」から「hello」という文字列をリダイレクトにより、trコマンドへ渡しています。このシェルスクリプトを実行すると、trコマンドにより大文字に変換され、「HELLO」と表示されます。
標準出力のリダイレクト
続いて、標準出力のリダイレクトを使ったサンプルを作成します。
#!/bin/sh dmesg > outfile
dmesgコマンドは起動時のログを表示させるコマンドです。このシェルスクリプトを実行するとカレントディレクトリ上に「outfile」という名前のファイルが作成されます。
そのファイルを開くと、dmesgが出力した起動時のログが記載されているはずです。
特別なファイル/dev/null
コマンドの出力を見る必要も保存する必要もないという場合には、/dev/nullというファイルにリダイレクトの出力先に変更します。
/dev/nullに出力されたデータは保存されることなく捨てられます。