1. TOPTOP
  2. Webサービス
  3. Linux

シェルスクリプト 標準入出力のリダイレクト記号について (標準入出力の変更・標準出力の末尾追加・標準エラー出力の変更)

|

shellscript_a_array_delcare

シェルスクリプトのコードを読んでいると、よく等号記号のような特殊記号を見かけます。

$ ls > result.txt

例えば上記のような記号です。lsコマンドの次に使われている記号は標準出力をリダイレクトするという意味です。調べてみるとリダイレクト記号は”>”以外にもあって、ややこしかったりするので例を出してまとめておきました。

なお今回の記事は、新しいシェルプログラミングの教科書(新しいタブで開く)を参考にさせていただいています。

標準入出力とリダイレクト

記事の冒頭で「標準出力をリダイレクトする」と書きました。リダイレクトを理解するための前提知識として、まず「標準出力」という言葉の意味を知る必要があります。

標準入出力について

ただシェルスクリプトでは「標準出力」の類語として、「標準入力」・「標準エラー出力」というキーワードもセットで知っておく必要があります。これら3つを合わせて標準入出力と呼びます。

標準入力 : 標準的な入力元。通常キーボード
標準出力 : 標準的な出力先。通常は端末ディスプレイ
標準エラー出力 : 標準的なエラーの出力先。通常は端末ディスプレイ

リダイレクトとは

リダイレクトとはコマンドを実行するときに標準入出力の入力元と出力先を置き換えるシェル機能のことを指します。

標準入出力のリダイレクトの実例

まず標準入出力のリダイレクトの実例を見ていきましょう。

標準出力のリダイレクトと例文

標準出力のリダイレクトをしてみましょう。

$ cat > fruits.txt
apple
grape
melon
(ctrl + D)

上記のcatコマンドは通常ではディスプレイに出力されますが、”>”を使うことによってfruits.txtに出力されます。

標準出力と例文

標準入力のリダイレクトをしてみましょう。シバムで始まるスクリプト(“fruits.sh”)は、fruits.txtに出力した果物リストに行番号を入力するスクリプトです。

#!/bin/bash
i=1
while read name; do
  echo $i "$name"
  ((i++))
done < fruits.txt
$ ./fruits.sh
1 apple
2 grape
3 melon

“fruits.sh”を実行すると、行番号付きでfruits.txtの内容が表示されます。

標準出力の追記と例文

標準出力のリダイレクトをファイルの末尾に追加してみましょう。

$ echo "Now On Sale!" >> fruits.txt
$ cat fruits.txt 
apple
banana
orange
Now On Sale!

上記の例ではfruits.txtに出力した果物リストに、”Now On Sale!”という文字列が追記されています。

標準エラー出力について

標準エラー出力をリダイレクトする場合、ファイルディスクリプタという識別子を使用します。ファイルディスクリプタについて、冒頭で紹介した「新しいシェルプログラミングの教科書」のP116を引用すると、下記のように説明されています。

プロセスから開かれたファイルには、すべてファイルディスクリプタと呼ばれる数値が割り当てられ、プロセスからファイルを参照する際の識別子となります。

識別子番号の種類

標準入力 → 0
標準出力 → 1
標準エラー出力 → 2

ファイルディスクリプタとして識別子の番号は上記のように割り当てられています。

$ ls > result.txt
$ ls 1> result.txt

冒頭で紹介したコマンドでは識別子を与えられていません。ですが識別子を省略した場合、”1″と同じに見なされますので、2つのコマンドの意味は同じです。

標準エラー出力をファイルにリダイレクト

標準エラー出力をファイルにリダイレクトする場合、”2>“という記号を使います。

$ ls /hoge 2> error.txt
$ cat error.txt
ls: cannot access /hoge: そのようなファイルやディレクトリはありません

上記の例では、あえてroot直下に存在しないファイルの表示を求め、そのエラーメッセージを”error.txt”に出力しています。

標準エラー出力をファイルに追記

標準エラー出力を既存のファイルに追記する場合、”2>>“という記号を使います。

$ ls /hoge 2>> fruits.txt
$ cat fruits.txt
apple
banana
orange
Now On Sale!
ls: cannot access /hoge: そのようなファイルやディレクトリはありません

上記の例では、あえてroot直下に存在しないファイルの表示を求め、そのエラーメッセージを”fruits.txt”に追記しています。