LinuC-1 - 101試験 - 1.03:GNUとUnixのコマンド - 1.03.3 ストリーム、パイプ、リダイレクトの使用

Last Update : August 21 2022 17:47:20

     

a. パイプとリダイレクト

1.標準入出力

「標準入力」とはキーボードからの入力、「標準出力」とはそれに対する出力結果(エラーも含む)を表示するところ、つまりディスプレイです。
Linuxでは、データをストリームとして扱うため、基本的なインターフェイスが3つ定められています。

  • 標準入力(0)・・・プログラムへの入力ストリームのこと。基本は、キーボードです。
  • 標準出力(1)・・・プログラムからの出力ストリームのこと。基本は、画面(顛末)です。
  • 標準エラー出力(2)・・・プログラムのエラー時に出力されるエラーメッセージ出力のストリームのこと。基本は、画面(顛末)です。
ストリーム

ストリームとは、データの入出力に伴うデータの流れのこと。

テキストストリーム

ひとかたまりのテキストデータのこと。複数行からなるテキストデータのこと。


2.パイプ

パイプ(pipe)とは、あるコマンドの標準出力を次のコマンドに渡す処理のことをいいます。
パイプを使った処理のことを「パイプライン処理」といいます。
コマンドとコマンドの間には縦線の記号「|」を使います。

$ ls | tee ls.txt
dir1
directory1
file1
ダウンロード
テンプレート
デスクトップ
ドキュメント
ビデオ
音楽
画像
公開
$ cat ls.txt
dir1
directory1
file1
ダウンロード
テンプレート
デスクトップ
ドキュメント
ビデオ
音楽
画像
公開

3.リダイレクト

リダイレクトは、 標準入出力や標準エラー出力をファイルに置き換える機能です。
標準出力をファイルに変更するのが、出力リダイレクト、標準入力をファイルから行うのが入力リダイレクトです。


(1)出力リダイレクト

>」や「>>」という記号を使うと、標準出力を画面からファイルに変更する事ができ、コマンドの実行結果を保存することができます。これらの記号を「リダイレクト」といいます。
「>」を使うと上書きでファイルに書き込みます。

$ ls -l > txtfile

これを実行すると、「ls -l」コマンドを実行した結果が「txtfile」というファイルに書き込まれます。
更にこのファイルに追記したいという時は「>>」を使います。

$ ls -l >> txtfile

そして、例外になりますが、「2>」や「2>>」という記号を使うと、上記の標準出力にかわって「標準エラー出力」、つまり処理結果がエラーだった時のメッセージをファイルに保存する事ができます。(標準入出力のカッコの数字)
例えば、「lpic-site」というファイルが存在しないにもかかわらず、「ls」コマンドでそのファイルを表示させたとします。

$ ls lpic-site
ls: lpic-site: No such file or directory

これを先ほどの「2>」を使って、エラー結果を「error-txt」に書き込んでみます。

$ ls lpic-site 2> error.txt

ここで「cat」コマンドで「error-txt」の内容を表示させてみると、

$ cat error.txt
ls: lpic-site: No such file or directory

● 出力リダイレクトの記号
 Command > file コマンドの標準出力をファイルに書き込む
 Command >> file
コマンドの標準出力をファイルに追加
 Command 2> file コマンドの標準エラー出力をファイルに書き込む
 Command 2>> file コマンドの標準エラー出力をファイルに追加
 Command > file 2>&1 コマンドの標準出力と標準エラー出力をファイルに書き込む
 Command >> file 2>&1 コマンドの標準出力と標準エラー出力をファイルに追加

最後の2つは、このリダイレクト「2>&1」を最後に追加すると、処理結果が正常かエラー、どちらの場合になってもファイルに書き込んでくれます。
「1」や「2」といった番号は、「ファイル記述子」といって、「1」が標準出力、「2」が標準エラー出力を意味しています。真中の「>&」は、左側に書かれたファイル記述子の出力を右側に書かれたファイル記述子の出力に変更する記号ですが、ここではとにかく「処理結果(正常かエラー)をファイルに保存する」ものだと考えて良いと思います。
ちなみに、処理結果が正常な場合とエラーの場合で、保存するファイルを分けたい場合は、
Command 1> file 2> errorfile
のように指定します。


(2)入力リダイレクト

入力リダイレクトの記号は、「<」と「<<」の2つしかありません。
入力リダイレクト「<」は、ファイル内の内容を標準入力としてコマンドを実行することができます。例えば、

$ grep lpic < /home/lpictxt

と入力すれば、「/home/lpictxt」というファイル内の「lpic」という文字列を含んだ行を表示します。ちなみに「grep」は、していした文字列(この場合は「lpic」)を含む行を表示するコマンドです。
続いて「<<」の説明です。これは「ヒアドキュメント」と言って、指定した文字列が入力されるまで標準入力からの入力を続けられるという記号です。

$ cat > lpictxt << text-end

というコマンドを実行すると、キーボードから入力した内容が「lpictxt」というファイルに書き込まれ、それが「text-end」という文字列が入力されるまで続きます。

● 入力リダイレクトの記号
 Command < file ファイルの内容を標準入力としてコマンドを実行する
 Command << 文字列
指定した文字列が入力されるまで、標準入力からの入力を続ける

特定の文字列が現れるまで、入力を続ける場合は、「 << 」のリダイレク記号を使います。これは「ヒアドキュメント」と呼ばれます。

終了文字列 end が出るまで入力を続ける場合

$ cat > test.txt << end > 1gyoume > 2gyoume > 3gyoume > end


4. tee コマンド

パイプやリダイレクトを使うと、標準出力に何も表示されません。いちいち出力ファイルを確認しなければなりません。そのようなときのために、tee コマンドがあります。teeコマンドは標準入力から読み込んだ内容を、標準出力とファイルの両方に出力します。

● tee コマンド構文
  tee [オプション] [ファイル名・・・]

● tee コマンドオプション
 -aファイルに上書きするのではなく追記する

● ファイルと標準出力両方に出力
# ls | tee sample
total 954 -rw-rw-r-- 1 user1 user1 684 Feb 26 15:11 sample1 -rw-r--r-- 1 user1 user1 422 Feb 26 10:24 sample2
# cat sample
total 954 -rw-rw-r-- 1 user1 user1 684 Feb 26 15:11 sample1 -rw-r--r-- 1 user1 user1 422 Feb 26 10:24 sample2

● 複数ファイルと標準出力両方に出力
# ls -al | tee sample1 sample2
total 954 -rw-rw-r-- 1 user1 user1 684 Feb 26 15:11 sample1 -rw-r--r-- 1 user1 user1 422 Feb 26 10:24 sample2

● ファイルに出力したあと、次のコマンドに渡す
# ls | tee sample1 | wc -l 3


5. xargs コマンド

xargs コマンドは、指定されたコマンド文字列と標準入力から読み込んだ引数を組み合わせてコマンド行を作成し実行します。コマンド文字列には、実行するコマンドとそのオプションまたは引数を指定します。

● xargs コマンド構文
  [コマンド] | xargs [オプション] [コマンド]

● xargs コマンドオプション
 -0渡される引数がヌル文字で区切られているものとする(findとの連携のため必要)
 -pコマンド実行毎に実行するかどうか確認してくる。yで実行、それ以外でスキップ。
 -L 数字指定行数ごとにコマンドを分けて実行させられる。
 -n 数字指定個数の引数ごとにコマンドを分けて実行させられる。
 -t実際に実行するコマンド文字列とその引数リストをファイル記述子 2 (通常は 標準エラー) に出力します。コマンドは省略すると、代わりにecho コマンドが呼び出されます。

● ファイル一覧から拡張子がtxtのファイルを探し、そのすべてをcatで表示する。その1
# find *.txt | xargs cat

上記の場合、ファイル名にスペースが入っている場合、その名前のファイルは表示できない。
xorgsコマンドはスペースやタブ、改行が入っていた場合、区切り文字となってしまい複数のファイルに分割されてしまいます。 そのためには、空白や特殊文字を含むファイルを正しく処理するため、findコマンドには必ず「-print0」オプションを付け「xargs -0」で受け取るようにします。「-0」オプションは「--null」でも構いません。
これにより、findコマンドは空白と改行ではなくヌル文字(\0)を区切りとして、検索結果を出力します。同様にxargsコマンドも、引数がヌル文字で区切られているものとして処理を行います。


● ファイル一覧から拡張子がtxtのファイルを探し、そのすべてをcatで表示する。その2
# find *.txt -print0 | xargs -0 cat
abcde abcdefg abcdef abcde abcdefg abcde a b c d e f g h 1 tokugawa 2 oda 3 toyotomi \:\:\: ここはヘッダーです \:\: ここは本文です ハードリンクのテストです 再度ハードリンクのテストです。 \: ここはフッターです ここでもハードリンクのテストです

● 1つの引数ごとに表示する。
# cat test5.txt
foo1 bar1 baz1 foo2 bar2 baz2 foo3 bar3 baz3
# cat test5.txt | xargs -n 1 -t
/bin/echo foo1 foo1 /bin/echo bar1 bar1 /bin/echo baz1 baz1 /bin/echo foo2 foo2 /bin/echo bar2 bar2 /bin/echo baz2 baz2 /bin/echo foo3 foo3 /bin/echo bar3 bar3 /bin/echo baz3 baz3

● 1行の引数ごとに表示する。
# cat test5.txt | xargs -L 1 -t
/bin/echo foo1 bar1 baz1 foo1 bar1 baz1 /bin/echo foo2 bar2 baz2 foo2 bar2 baz2 /bin/echo foo3 bar3 baz3 foo3 bar3 baz3


z. 出題範囲概要

概要 :
  • テキストデータを効果的に処理するためにストリームのリダイレクトや接続ができる。
  • この作業には標準入力、標準出力、標準エラー出力へのリダイレクト、あるコマンドの出力を別のコマンドの入力にパイプする、あるコマンドの出力を別のコマンドの引数として使用する、出力を標準出力とファイルの両方に送るといったことが含まれる。

詳細 :
  • 標準入力、標準出力、標準エラー出力をリダイレクトする。
    <, >, >>, 2>&1
  • あるコマンドの出力を別のコマンドの入力にパイプする。
    | (縦線)
  • あるコマンドの出力を別のコマンドの引数として使用する。
    xargs
  • 出力を標準出力とファイルの両方に送る。
    tee

  [ 例題 ] 


         

    www.it-shikaku.jp