Mazn.net

やってみて 調べてみて 苦労しなけりゃ 箱は動かじ

標準出力と標準エラー出力を入れ替える方法@bash

      2013/07/15

標準出力と標準エラー出力を入れ替える方法を、結論だけを先に書くと

3>&2 2>&1 1>&3

というリダイレクトを行うと可能です。

 

以下は、あまりリダイレクトに詳しくない人向けに説明書いてみました。

ファイルディスクリプタは、0番が標準入力、1番が標準出力、2番が標準エラー出力です。例えば、index.html というファイルがあり、abc.htmlが無いディレクトリで以下のコマンドを実行したとすると、以下のように表示されます。

# ls -l index.html abc.html
ls: cannot access abc.html: そのようなファイルやディレクトリはありません
-rw-r--r-- 1 root root 0  4月 30 15:54 2012 index.html

このとき、見た目はわかりませんが、結果1行目の”ls: cannot access abc.html: そのようなファイルやディレクトリはありません” というのが標準エラー出力、2行目の”-rw-r–r– 1 root root 0  12月 30 15:15 2012 index.html” が標準出力になります。

この二つの違いを知るには、単純に標準出力をリダイレクトしてみるとわかります。

# ls -l index.html abc.html > log.txt
ls: cannot access abc.html: そのようなファイルやディレクトリはありません

このように、”>” は標準出力だけをリダイレクトするため、標準出力だけがlog.txtに書き込まれ、標準エラー出力はそのまま画面に出力されます。

# ls -l index.html abc.html 2> log.txt
 -rw-r--r-- 1 root root 0  4月 30 15:54 2012 index.html

 

次は、パイプを使って結果を処理することを考えたいと思います。今回は、よく使われるgrepを使います。

# ls -l index.html abc.html | grep index
 ls: cannot access abc.html: そのようなファイルやディレクトリはありません
 -rw-r--r-- 1 root root 0  4月 30 15:54 2012 index.html

はい。知っている人には当たり前ですが、”index”という文字列をgrepしたのに、エラーの内容も表示されました。これは、パイプが標準出力だけをgrepの入力として処理し、標準エラー出力はパイプに渡されずにそのまま画面に出力されてるためです。

標準エラー出力もgrepで処理したい場合は、以下のように標準エラー出力を標準出力にリダイレクトしてあげることで解決します。

# ls -l index.html abc.html 2>&1 | grep index
 -rw-r--r-- 1 root root 0  4月 30 15:54 2012 index.html

 

では標準エラー出力だけをgrepし、標準出力はそのまま画面に出力させたい場合はどうすればよいのでしょうか?

言い換えれば、標準出力と標準エラー出力を入れ替えるにはどうすればよいでしょうか?

 

bashには、リダイレクトを入れ替えるという機能はありません。そこで登場してもらうのが、3番のファイルディスクリプタです。考え方は、標準出力(1番)を一時的に3番に退避し、標準エラー出力(2番)を1番にリダイレクト、退避していた3番を2番にリダイレクトするという方法です。これをコマンドで書くとこのようになります。
※説明の順番を以下のようにコマンドの後ろから書いていく必要があります。

# ls -l index.html abc.html 3>&2 2>&1 1>&3
 ls: cannot access abc.html: そのようなファイルやディレクトリはありません
 -rw-r--r-- 1 root root 0  4月 30 15:54 2012 index.html

見た目では分かりませんが、これで入れ替わりました。先ほどと同じようにgrepしてみましょう。

# ls -l index.html abc.html 3>&2 2>&1 1>&3 | grep index
 -rw-r--r-- 1 root root 0  4月 30 15:54 2012 index.html

はい。最初のgrepの例と異なり、”ls: cannot access abc.html: そのようなファイルやディレクトリはありません”だけがgrepの対象になり、、”-rw-r–r– 1 root root 0  4月 30 15:54 2012 index.html” は標準エラー出力として出力されているためそのまま画面に出力されました。

この例だと、grepでマッチしているように見えるので、違う文字列をgrepしてみます。

# ls -l index.html abc.html 3>&2 2>&1 1>&3 | grep def
 -rw-r--r-- 1 root root 0  4月 30 15:54 2012 index.html
# ls -l index.html abc.html 3>&2 2>&1 1>&3 | grep abc
 ls: cannot access abc.html: そのようなファイルやディレクトリはありません
 -rw-r--r-- 1 root root 0  4月 30 15:54 2012 index.html

ちゃんと入れ替わってるでしょ?

 - IT技術, サーバ構築, プログラミング ,

336px

Message

メールアドレスが公開されることはありません。

  関連記事

Windows10にssh-agentをインストール

WindowsのPowerShell向けのssh-agentをインストールしてみ …

no image
IPアドレスの範囲からサブネットマスクを簡単に計算する@CentOS 5

ちょっとしたアタックがあるIPからあった場合に、whois で IP の情報調べ …

no image
Sony VAIO Z (VPCZ22) にLinux (Fedora 16)入れてみた

Sony VAIO Z (VPCZ22) SSDベンチマークに引き続き、Fedo …

no image
Google Music の文字化け対策まとめ

まだ日本ではサービス開始されていませんが、Google Music が便利そうな …

no image
USBハードディスクにWindows 7インストール

今あるPCのシステムを消したくなかったので、USBハードディスクにWindows …

no image
linuxのSWAPパーティッションにUUIDを指定する

ext3とかext4のパーティッションはtune2fsでUUIDを指定できますが …

no image
LVM覚え書き@Fedora14

LVMの使い方をすぐ忘れてしまうので、覚え書き。 LVM用のパーティションを用意 …

no image
アイソレーションレベル

データベースはあまり詳しくないので、メモ書き。 SQL-92の仕様では、アイソレ …

no image
Galaxy SIIIのカメラのシャッター音を消す@Android 4.1.2

root 化した端末必須です。 root 権限で実行でき、/system を読み …

no image
Debianの起動スクリプト編集@Debian Etch

Red Hat系ではchkconfigというコマンドで起動スクリプトのon/of …