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

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

  関連記事

no image
PS3のアップデートチェック

PS3をインターネットに繋いでいると、起動時にソニーのサイトにアップデートチェッ …

no image
screenからtmuxに乗り換えてみる

screenからtmuxに乗り換えた時のメモ。 まずは、ネットの情報を参考に、~ …

no image
スイッチの初期化 @ Cisco Catalyst 2960

スイッチのパスワードを忘れてしまいログインできなくなった場合は初期化することにな …

no image
or条件でのgrep

普段使ったことなかったので覚え書き。 grep で複数の文字列をor条件でマッチ …

no image
システム上のユーザ一覧情報の取得

NISやLDAPなどを使用していると、きちんとと設定されているのか、誰が認証でき …

no image
ネットワークの遅延を発生させる@CentOS 5

検証などでネットワーク遅延を発生させたい場合、qdisc を使って簡単に実現でき …

no image
githubへのhttps(ssl)アクセスに証明書を使う@Cygwin

Cygwin上のgitで、githubからhttpsでcloneしようとしたら証 …

no image
起動時にswaponを実行して、スワップを有効にする @ Android Galaxy S with root

Galaxy S は、Google Map 使うとフリーズしてしまうが、スワップ …

no image
cygwin上にSphinxをインストール

Cygwin 上に Sphinx をインストールしたときのメモです。 pytho …

no image
ディスクイメージをデバイスファイルとして扱う@CentOS5.4 + Xen

※ 2015/4/30追記 : mountオプションで直接マウントする方法を書き …