コマンドの結果を画面とパイプの両方に渡す方法
- 2015-02-16
- カテゴリ: Client Side
- タグ: Tips Linux Zsh
コマンドの結果を画面とパイプの両方に流す方法をいくつか調べたのでメモ。
やりたいのは、以下のような処理でpbcopy
に渡った標準出力を、画面からも確認すること。
find . -type f | pbcopy
なお、pbcopy
は標準入力をクリップボードに送るOS Xのコマンド。
方法1. Multios
zshなら、画面に出力するだけであればとても簡単。以下のように、標準出力を標準エラー出力にリダイレクトするだけでよい。
find . -type f >&2 | pbcopy
zshでは、Multiosという機能のおかげでリダイレクト先を複数個指定することができるので、標準エラー出力へのリダイレクトとパイプへの出力が同時にできる。
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 >barwrites the date to two files, named ‘foo’ and ‘bar’. Note that a pipe is an implicit redirection; thus
date >foo | catwrites 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)
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