Linuxのリダイレクト処理とパイプライン処理ついて備忘録としてまとめます。
確認した環境
- Ubuntu 16.04LTS
リダイレクト処理
リダイレクトとは
Linuxにおけるリダイレクトとは、大まかに言うとデータの入出力先を変更することです。
標準入力と標準出力
Linuxコマンドにおいては、特に指定がない場合はデータの入力を標準入力、データの出力を標準出力と呼び、それぞれデフォルトがキーボード入力、端末(ターミナル)画面出力となっています。また、出力にはエラー出力(標準エラー出力と呼びます)もあります。下表を参照ください。
入出力 | 識別番号 | デフォルト | 備考 |
---|---|---|---|
標準入力 | 0 | キーボード入力 | データ入力など |
標準出力 | 1 | 端末(ターミナル)画面 | コマンドやプログラムの実行結果 |
標準エラー出力 | 2 | 端末(ターミナル)画面 | コマンドやプログラムのエラーメッセージ |
Linuxでのリダイレクトは、例えば
- プログラムの実行結果の出力先を、端末画面からファイルに変える
- データ入力をキーボード入力からファイルからのデータ読み込みに変える
- プログラムのエラーメッセージの出力先を、端末画面からファイルに変える
といった処理となります。以下の章でもう少し詳しく見ていきます。
標準出力のリダイレクト
記号 > を使います。例えば、あるコマンドの出力先を標準出力(端末画面)からファイルに変更する場合は以下のように書きます。
コマンド > ファイル
catコマンドの例を以下に示します。
#catコマンドの出力を標準出力からファイルに変更
$ cat > file1
one
two
three
four
#ctrl + D押下(EOF)で入力終了
#作成したファイルを確認
$ cat file1
one
two
three
four
また、例えばPythonスクリプトの実行結果をファイルに格納したい場合もリダイレクトが使えます。
まず、以下のPythonスクリプトsample01.pyを準備します。”Hello, world”を出力する単純なプログラムです。
#サンプルプログラムsample01.py
$ cat sample01.py
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
print("hello, world")
普通にコマンドラインから実行すると、標準出力(=端末画面)に結果が出力されます
$ python3 sample01.py
hello, world
プログラムの実行結果をファイルにリダイレクトします。この場合、標準出力には何も表示されません
$ python3 sample01.py > sample01.txt
リダイレクト先に設定したファイルにプログラムの実行結果が格納されていることが確認できます。
$ cat sample01.txt
hello, world
標準出力のリダイレクト(追記)
記号 >> を使うと出力をファイルに追記できます。
コマンド >> ファイル
上記のpythonスクリプトsample01.pyを引き続き例として使うと、
#Pythonスクリプトの実行結果をファイルへ追記モードでリダイレクト
$ python3 sample01.py >> sample01.txt
#リダイレクト先のファイルにプログラムの出力結果が追記されています。
$ cat sample01.txt
hello, world
hello, world <-- 追記されている
標準入力のリダイレクト
標準入力のリダイレクトは、記号 < を使います。コマンドへの入力を標準入力からファイル入力に変更する場合は以下のように書きます。
コマンド < ファイル
以下のPythonプログラムsample02.pyを例にします。
#EOF(Ctrl +D入力)が読み込まれるまで入力された文字列を出力し続ける
$ cat sample02.py
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
while(True):
try:
n = input()
print(n)
except EOFError:
break
通常のスクリプト実行時は、入力一行毎に標準出力(=端末画面)に結果を返します。
$ python3 sample02.py
one #入力
one #結果出力
two
two
three
three
four
four
#最後にctrl+DでEOFを入力してプログラム終了
次に、標準入力のリダイレクト処理の例を示します。まずファイルからの入力用として以下のファイルを準備しました。
$ cat input_data
five
six
seven
eight
pythonスクリプトへの入力を標準入力から上記で準備したファイルに変更します。この場合はプログラムの出力結果は標準出力に表示されます。
$ python3 sample02.py < input_data
five
six
seven
eight
上記の標準入力と標準出力のリダイレクトを組み合わせて、ファイルからデータ入力して結果をファイルに格納するという処理もできます。
#Pythonスクリプトへの入力をファイルinput_dataへ変更し、
#実行結果をファイルresult01に出力
$ python3 sample02.py < input_data > result01
#処理結果はリダイレクト先のファイルに格納されています。
$ cat result01
five
six
seven
eight
終端文字列を指定する
ここで、記号 << についても触れておきます。>> は標準出力のリダイレクトの追記モードでしたが、<<は意味が異なります。<< は、終端文字列を指定する機能です。次のように使います。
コマンド << 終端文字列
catコマンドを使った例を以下に示します。
#終端文字を_END_として、testファイルを作成
cat << _END_ > test
> one
> two
> _END_
#作成したファイルの内容を確認
$ cat test
one
two
標準エラー出力のリダイレクト
標準エラー出力をファイルにリダイレクトするには、2> を使います。ここで2は標準エラー出力の識別番号です。尚、2>> とするとファイルへの追記モードになります。
ちなみに上記の標準出力や標準入力の > や < は、それぞれ1> 、0<の省略形でした。
エラー出力の例として、上記と同じプログラムsample02.pyでエラーを発生させます。
python3 sample02.py
a
a
b
b
^C #ctrl+C押下でKeyboardInterruptエラーを発生させる
#デフォルトだとエラーメッセージが端末画面に表示されます
Traceback (most recent call last):
File "sample02.py", line 6, in
n = input()
KeyboardInterrupt
標準エラー出力をファイルへリダイレクトさせます。
$ python3 sample02.py 2> error.log
a
a
b
b
^C <-- Ctrl + C押下でKeyboardInterruptエラー発生
#ここで、端末画面にはエラーは表示されません。
#ファイルの中身を確認。リダイレクト先のファイルにエラーメッセージが格納されています。
$ cat error.log
Traceback (most recent call last):
File "sample02.py", line 6, in
n = input()
KeyboardInterrupt
標準出力と標準エラー出力のリダイレクト
標準出力と標準エラー出力のリダイレクトを同じファイルに書き込むには、
コマンド > ファイル 2>&1 または コマンド &> ファイル
と書きます。例を以下に記載します。
#sample02.pyの実行結果とエラー出力をファイルresult02に出力
$ python3 sample02.py > result02 2>&1
one
two
three
#結果を確認
$ cat result02
one
two
three
Traceback (most recent call last):
File "sample02.py", line 6, in
n = input()
KeyboardInterrupt
または、
#sample02.pyの実行結果とエラー出力をファイルresult03に出力
$ python3 sample02.py &> result03
one
two
three
^C
#結果を確認
$ cat result03
one
two
three
Traceback (most recent call last):
File "sample02.py", line 6, in
n = input()
KeyboardInterrupt
また、標準出力と標準エラー出力のリダイレクトをそれぞれ別ファイルに出力するには、
コマンド > ファイル1 2> ファイル2
と書きます。ファイル1にコマンド実行結果、ファイル2にエラー出力が書き込まれます。
#sample02.pyの実行結果をファイルresult03に、エラーメッセージをerror03.logに出力
$ python3 sample02.py > result03 2> error03.log
one
two
three
^C
#結果を確認
#プログラムの実行結果
$ cat result03
one
two
three
#エラー出力の格納
$ cat error03.log
Traceback (most recent call last):
File "sample02.py", line 6, in
n = input()
KeyboardInterrupt
パイプライン処理
パイプライン処理は、コマンドやプログラムの出力を別のコマンドやプログラムの標準入力に直接渡す処理のことで、|で表します。
コマンド1 | コマンド2 ・・・
のように使います。例えば、grepコマンドと組み合わせて、特定の文字列を含んだ内容を抽出するのにも使われます。
$ls -l | grep test
$ps aux | grep apache
まとめ
Linuxのリダイレクト処理とパイプライン処理についてまとめました。
<リダイレクト>
コマンド > ファイル | コマンドの出力をファイルに上書き |
コマンド >> ファイル | コマンドの結果をファイルに追加 |
コマンド < ファイル | ファイルのデータをコマンドの入力にする |
コマンド << 文字列 | 終端文字列を指定 |
コマンド 2> ファイル | コマンドのエラー出力をファイルに上書き |
コマンド 2>> ファイル | コマンドのエラー出力をファイルに追加 |
コマンド > ファイル 2>&1 | コマンドの出力とエラー出力をファイルに上書き |
コマンド &> ファイル | コマンドの出力とエラー出力をファイルに上書き |
コマンド < ファイル1 2> ファイル2 | コマンドの出力をファイル1に、エラー出力をファイル2に上書き |
<パイプライン>
コマンド1 | コマンド2 | コマンド2の結果をコマンド2に渡す |