4,708 バイト追加
、 2020年2月15日 (土) 07:33
==Linux ストリーム、パイプおよびリダイレクト==
[Linux][Linux コマンド]
{{amazon|487311070X}}
*Linux,Unix の優れた考え方の一つがすべてをファイルとして取り扱えるということ
*ディスクドライブ、パーティション、端末、マウスすべてがファイルシステムに対応付けられるため同じ方法でデータをやりとりできる
*このためプログラムのインターフェースを単純にできる
*ファイルの概念を利用するデバイスには、デバイスファイルが提供される
*例えば端末のデバイスファイルを読み込んでいるプログラムは、キーボードから入力文字を受け取り、端末デバイスファイルに書き込むと端末の画面に表示される
===標準I/Oとデフォルトのファイル記述子===
====標準入力(stdin)====
*テキスト入力ストリーム
*デフォルトではキーボードが標準入力
*ファイル記述子0とも呼ばれる
====標準出力(stdout)====
*通常のプログラム出力ようのテキスト出力ストリーム
*デフォルトでは端末が標準出力先
*ファイル記述子1とも呼ばれる
====標準エラー(stderr)====
*テキスト出力ストリームだが、エラーなどの情報にのみ使用される
*デフォルトでは端末が標準エラー出力先
*標準出力と同じく端末が出力先のため、混在して表示される
*ファイル記述子2とも呼ばれる
===パイプ===
*プログラムから見るとテキストデータをファイルから読むのとキーボードから読むのとに違いはない
*データの書き込み先が、ファイルだろうとディスプレイであろうと処理は同じ
*この考えをひろげると、あるプログラムの出力を別のプログラムの入力にすることができる
*このために使用するのがパイプ | で2つ以上のコマンドを結合できる
$ grep "01523" order* | less
===リダイレクト===
*パイプ記号は一方のコマンドの出力を他方の入力にするようにシェルに指示するが、これは特殊なリダイレクトと言える
*リダイレクトでは、入力ストリームの作成元と出力ストリームの宛先を管理できる
====リダイレクト演算子 > で出力を直接ファイルに送る====
*リダイレクト演算子 > を使用することで、iノード番号のリストを直接ファイルに送る例
$ ls -i * | awk '{print $1}' | sort -nu > in.txt
*シェルは空のファイル(in.txt)を作成し、ファイルを書き込み可能とする。そして、結果を標準出力ではなく、このファイルに出力する
====リダイレクト演算子 >> で出力を既存のファイルに追加する====
*in.txt に脚注を1行追加する例
$ echo "end of list" >> in.txt
*存在していれば追記、なければ新規作成が行われる
====標準入力のリダイレクト <====
*キーボードではなくファイルの内容を入力に使用する
=====in.txt の内容を記載したメールメッセージをユーザー jdean に送信=====
*通常Mailプログラムは端末からの入力をユーザーに求めるが、標準入力をin.txtに
リダイレクトするとMailはユーザーに入力を求めることなく処理を実行
$ Mail -s "inode list" jdean < in.txt
====bashシェルの標準I/Oリダイレクト====
{|class="wikitable"
!リダイレクト機能
!書式1
!書式2
|-
|stdoutをfileに
|$ cmd > file
|$ cmd 1> file
|-
|stderrをfileに
|$ cmd 2> file
|-
|stdoutとstderrの両方をfileに
| $cmd > file 2>&1
|-
|stdoutをファイルに、stderrをfile2へ
|$ cmd > file 2 > file2
|-
|fileからstdinをうけとる
|$ cmd < file
|-
|file にstdoutを追加する
|$ cmd >> file
| $ cmd 1>>file
|-
|file にstderrを追加する
|$ cmd 2>> file
|-
|file にstdoutとstderrの両方を追加する
|$ cmd >>file 2>&1
|-
|cmd1 のstdoutを cmd2にパイプでつなぐ
|$ cmd1 | cmd2
|-
|cmd1 のstdout
|
|-
|cmd1 のstdoutとstderrをcmd2にパイプでつなぐ
|$ cmd1 2>&1 cmd2
|-
|}
====teeコマンド====
*プログラムを実行したとき、出力をファイルに送り同時に画面にも表示したい場合に使用する
*cmd1、cmd2、cmd3の書くコマンドからなるパイプラインを実行したい場合、最後の結果がfile1に書き込まれる
$ cmd1 | cmnd2 | cmd3 > file1
*cmd1の中間結果を参照したい場合、file_cmd1ファイルを新規に作成して中間結果を書き込むには、teeを使用する
$ cmd1 | tee file_cmd1 | cmd2 | cmd3 > file1