ぱそくま ろご
Linux > シェル > bash リダイレクト(出力)

bash リダイレクト(出力)

リダイレクトとは

リダイレクトとは出力先や入力先を変えることです。 通常、コマンドを入力した結果が画面に表示されます。これは出力先が画面になっているためです。 リダイレクトを使うと出力先を画面からファイルなどに変更することができます。 出力の変更先はファイル名またはファイルディスクリプタというものを使用します。

ファイルディスクプリタ

ファイルディスクプリタとはリダイレクトで使用される数値で、その数値はファイルをを識別するために使用します。 また、それ以外にも端末上には常に3つの特殊なファイルが開いています。 標準入力(0 キーボード)と標準出力(1 画面)と標準エラー出力(2 画面)です。 特殊なファイルのディスクプリタはかっこ内の通りで、3以降(9まで)が任意のファイルに割り振ることができます。 ディスクプリタがピンとこないかも知れませんが、このページを全て読むとピンとくるかもしれません。

出力リダイレクト - >

不等号(より大)を使うと出力先を変更(redirection)することができます。例えば、出力先を標準出力からファイルに変更できます。

リダイレクトを使ってファイルに出力

[paso ~]echo hello > result.txt
[paso ~]more result.txt
hello

>の前には実は1が省略されていて、正確には「echo hello 1> result.txt」となります。 1はファイルディスクプリタで、標準出力を表します。



なお、>の前に「&」をつけるとディスクプリタ1,2を同時に指定したことになります。 この方法はbash 4以降でのみ利用可能です。

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

[paso ~]apt-get install lftp &> result.txt
[paso ~]more result.txt
Reading package lists... Done
Building dependency tree
.
.
.
  404  Not Found [IP: 203.178.137.175 80]
Failed to fetch http://ftp.jp.debina.org/debian/pool/main/l....
.
E: Unabel to fetch some archives, maybe run apt-get update or try with 
--fix-missing?

標準エラーの出力先を標準出力に変更したい場合は>の後ろにファイルディスクプリタ「1」の複製を指定する必要があります。 複製するには&をつけます。

標準エラー(2)を標準出力(1)にリダイレクト

[paso ~]apt-get install lftp 2>&1

今までの方法では、リダイレクト先が常に上書きされます。リダイレクト先がファイルなどの場合、 追加して出力したい時があると思います。この場合は、より大「>」を2つ続けます。

リダイレクト(追加)

[paso ~]echo I >> result.txt <- ファイルがなければ新規作成
[paso ~]echo hava >> result.txt
[paso ~]echo a dog.>> result.txt
[paso ~]more result.txt
I
hava
a dog.

「:(コロン)」はダミーのプレースホルダーです。よって、これを使うと 「echo > file」と同じことができます。

ファイルの内容を空にする

[paso ~]more result.txt
I
hava
a dog.
[paso ~]: > result.txt
[paso ~]more result.txt
[paso ~]

ファイルディスクプリタを使う

今ままでのコマンドライン上のみでおこなうと、リダイレクトは一方通行でかつ直ぐに閉じてしまいます。 しかし、execコマンドと併用して使用すると任意のファイルディスクプリタを入力と出力の両方の状態で開くことができます。 例えば、ファイルの中身にを読んで、その内容に応じてそのファイルの最終行に追加することも可能になります。 また、/dev/tcp/の特殊ファイルを使えば、HTTP通信も可能です。

bashでHTTP通信

[paso ~]more get_paso.sh
exec 3<>/dev/tcp/www.pasokuma.net/80 tcpの特殊ファイルをディスクプリタ3で開く
echo -e "GET / HTTP/1.1\r\nHost: www.pasokuma.net\r\nAccept-Language: ja\r\nConnection: close\r\n\r\n" >&3
cat <&3 入力をキーボードからディスクプリタ(3)に変更=(ファイルの中身)
exec 3>&- ディスクプリタ(3)を閉じる
[paso ~]sh http.sh | more
HTTP/1.1 200 OK
Date: Mon, 1 Nov 2000 12:12:12 GMT
Server: Apache
Accept-Ranges: bytes
Connection: close
.
.