コマンドの結果を画面とパイプの両方に渡す方法

スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

コマンドの結果を画面とパイプの両方に渡す方法

コマンドの結果を画面とパイプの両方に流す方法をいくつか調べたのでメモ。

やりたいのは、以下のような処理でpbcopyに渡った標準出力を、画面からも確認すること。

find . -type f | pbcopy

なお、pbcopyは標準入力をクリップボードに送るOS Xのコマンド。

方法1. Multios

zshなら、画面に出力するだけであればとても簡単。以下のように、標準出力を標準エラー出力にリダイレクトするだけでよい。

find . -type f >&2 | pbcopy

zshでは、Multiosという機能のおかげでリダイレクト先を複数個指定することができるので、標準エラー出力へのリダイレクトとパイプへの出力が同時にできる。

zsh: 7. Redirection

7.2 Multios

If the user tries to open a file descriptor for writing more than once, the shell opens the file descriptor as a pipe to a process that copies its input to all the specified outputs, similar to tee, provided the MULTIOS option is set, as it is by default. Thus:

date >foo >bar

writes the date to two files, named ‘foo’ and ‘bar’. Note that a pipe is an implicit redirection; thus

date >foo | cat

writes the date to the file ‘foo’, and also pipes it to cat.

方法2. tee /dev/stderr

検索するとよくヒットするのが↓の方法。teeで標準出力と/dev/stderrの両方に書き込む。

find . -type f | tee /dev/stderr | pbcopy

枯れた方法なのでshでもbashでもzshでも機能するけど、デバイスファイルを直接指定して出力するあたりがあまりエレガントじゃなくて、いまいち。

[追記()] 以下のように、teeをappendモードで起動しないとシェルスクリプトの中などで使ったときに壊れることがわかったので、注意喚起。

find . -type f | tee -a /dev/stderr | pbcopy

方法3. プロセス置換

もう一つの方法は、パイプの代わりにteeとプロセス置換を使う方法。zshとbashなら機能する。

find . -type f | tee >(pbcopy)

zsh: 14. Expansion

14.2 Process Substitution

Each part of a command argument that takes the form ‘<(list)’, ‘>(list)’ or ‘=(list)’ is subject to process substitution.

この方法のメリットは、画面に出力されるのが標準出力なので、再度リダイレクトしたりパイプに流し込んだりできる点。

find . -type f | tee >(pbcopy) | sort

画面に結果が表示されると、ついついリダイレクトしたくなるものなので、なにげに便利。

処理の途中結果をpbcopyのようなコマンドに適宜書き出しながら処理を進めたい場合などに力を発揮するが、そういった用途の場合、普通はファイルへの書き出しで間に合うので、ただのteeで十分かも。

結論

  • 手元の環境だと方法3が使いやすいので、しばらくはこれで様子見
  • zshはすごい
スポンサーサイト

関連記事

トラックバック URL

http://liosk.blog103.fc2.com/tb.php/215-f092f2a6

トラックバック

コメント

コメントの投稿

お名前
コメント
編集キー
 
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。