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

Linux
この記事は約6分で読めます。

Linuxのコマンドラインはただでさえ難解ですが、中でもとりわけ難解(少なくとも私にとっては)なのが、標準入出力・エラー出力のリダイレクトの構文です。

私にとってはこれもう、殆ど呪文でした。

これまで何度も、「忘れる → 調べる→ また忘れる。」を繰り返してきましたが、もう繰り返さないぞ!

というわけで、このテーマで投稿して(私用に)記録に残しておきます。

” リダイレクト ” という用語は、あるサイトに接続すると別のサイトに飛ばされる設定も ” リダイレクト ” と呼ばれますが、今回はその意味ではありません。

ファイルディスクリプタ値(FD値)

ファイルディスクリプタ値(FD値)は、「プロセスが開いたリソースを管理する数値」となっています。

何にことやらさっぱり分かりませんが取りあえずまずはそこは置いておいて、

この数値の0が標準入力、1が標準出力、2が標準エラー出力と定義されています。

ファイルディスクリプタ値
(FD値)
意味デフォルト値
0標準入力キーボード
1標準出力ディスプレイ
2標準エラー出力ディスプレイ

普段はデフォルト値に設定されているので、コマンドはキーボードから入力し、結果やエラー表示はディスプレイから出力されます。

FD値は3以上の値の内容も設定できます。

標準入力・標準出力・標準エラー出力のリダイレクト

この0~2の数値の内容を変更すると、標準入力元or標準出力先or標準エラー出力先が変わります。

これを(標準入力or標準出力or標準エラー出力)のリダイレクトと呼びます。

数値そのものを変更するのでなく、数値は単なる格納倉庫の表札であり、その倉庫に格納されている内容が変更されます。(ここが大事)

FD値を倉庫に例えて(2段目)、表を再掲すると下表になります。

FD値意味格納されている
デフォルトの内容
リダイレクトによる変更
倉庫に例えると
倉庫番号
倉庫の目的最初に倉庫に入っている物品入替可能な物品
0 標準入力キーボード任意のファイルなどに変更可能
1標準出力ディスプレイ任意のファイルなどに変更可能
2標準エラー出力ディスプレイ任意のファイルなどに変更可能
3以降未定未設定任意のファイルなどに変更可能

最も頻繁に行われるリダイレクトは入力元や出力先を、ファイルに変更することです。

なおFD値は、 ” < ” や ” > ” の直前直後に付ける数値です。(間にスペースを挟まずにくっついています。後述)

リダイレクトの実際

標準入力・標準出力・標準エラー出力の切替をリダイレクトと言います。

入力元をファイルに変更

” < ” の前後にスペースが開いていることに留意

出力先をファイルに変更

” > ” の前後にスペースが開いていることに留意

或いは、下記でも同じです。(むしろこちらが正式で、上記がその省略形。上記はそもそもデフォルトと同じ指定なので省略されている訳です)

” FD値1 ” (標準出力先)を、出力ファイル名に変更、という意味です。

” 1 ” と ” > ” の間にスペースが無いことに留意! ← これが重要

エラー出力先をファイルに変更

” FD値2 ” (標準エラー出力先)を、出力ファイル名に変更、という意味です。

上記の例では、存在しない ” xxx ” というディレクトリの内容を表示しようとしたせいでエラーが出たけど、そのエラーはディスプレイに表示されずに、 ” error.txt ” というファイルに書き込まれています。

” 2 ” と ” > ” の間にスペースが無いことに留意!

出力とエラー出力先を同じファイルに出力

以下の2つは同じ意味で、出力とエラー出力が同じファイルに書き出されます。

” & ” と ” > ” の間にスペースが無いことに留意!

上書きと追記

” > ” は上書きであり、これを ” >> ” に置き換えると追記にします。

下記はコマンド出力をファイルに上書き(既存ファイルの内容は消える)

下記はコマンド出力をファイルに追記(既存ファイルの内容が残る)

難解な構文の解釈

下記構文はスクリプトなどに頻回に出てきますが、最初は全然意味が分かりませんでした。(よく出る構文はほぼこの1パターンだけです)

これは出力とエラー出力を両方とも同じファイルに書き込む構文です。

最初の ” > ” は前後にスペースあり、2つ目の ” > ” には前後にスペースが無いことに留意

つまり前述の ” &> ” や ” >& ” 構文と同機能の構文です。前述の方法が新しく、こちらは古い方法です。

参考)

参考までに ” > ” の前後にスペースを開けるとエラーになります。

解釈

コマンド再掲

まずこれ、どこに切れ目があるのかが一目では分かりません。最初はここから躓いて苦労してました。

これは以下の2つに分けて考えます。

前段の意味はこれまでに説明した通りです。問題は後段です。

” 2>&1 ” はFD2の内容にFD1の内容をコピーして入れるという意味です。( ” & ” は複製するという意味)

前段の時点で、FD1の内容には ” ファイル名 ” が入っていますので(つまり標準出力がファイルに変わっているので)、後段で、FD2の内容もそれがコピーされて ” ファイル名 ” に変わります(なので標準エラー出力先も同じファイルに変わります。)

ゴミ箱に入れる

” /dev/null ” がゴミ箱です。のでここに向けて出力すると破棄されます。

関連事項

リダイレクトの関連コマンドです。

2つのコマンドの接続

これは有名ですが、パイプ ” | ” を使います。

コマンド1の結果をコマンド2に直接渡す。

枝分かれして両方向に出力

” tee ” コマンドを使います。(teeは ” T ” の意味=枝分かれの意味)

コマンド1の結果を、ディスプレイにも出力し、ファイル1にも書き出す。

まとめ

今回は、私の個人的謎解き記事でした。

謎解きすると何という事はなさそうですが、これがスクリプトの途中とかに予告なく出てくると、いつも頭に???が湧いていました。

要は、

ということです。

コメント

タイトルとURLをコピーしました