echoと/bin/echo

echoにはシェルの内部コマンドのechoと/bin/echoがあります。
echoの移植性のなさ(改行抑止)で示したような混乱もまねくのですが、シェルの内部コマンドとしてのechoには便利な点もあります。それは通常コマンドと違い引数の長さに制限がないことです。(だいたいの最大長はgetconf ARG_MAXで確認できます)


たまに1つのディレクトリに大量のファイルが格納されていて、ワイルドカードで引数を指定できない場合があります。(最初にやるのは設計者に文句を言うことだと思います)

$ grep ERROR *
 -bash: /bin/grep: 引数リストが長すぎます

この場合はlsとxargsを使えばいいでしょう。

$ ls | xargs grep ERROR
log20081224.02034:DANGEROUS ERROR
log20090119.00011:DANGEROUS ERROR

じゃちょっと絞り込んだワイルドカードを使うこんな時は?

$ grep ERROR *200910*
 -bash: /bin/grep: 引数リストが長すぎます

これはlsでは対処できません。

$ ls *200901* | xargs grep ERROR
 -bash: /bin/ls: 引数リストが長すぎます

前置きが長くなりました。ここでechoの出番です。

$ echo *200901* | xargs grep ERROR
log20090119.00011:DANGEROUS ERROR


まれなことではありますがこれを知らずに毎回ls | grep 200901 | while read l;do...などとやるのも悔しいものです。



ちなみに上記の場合、xargsでは最後の最後に引数1つだけでgrepが実行されてそこだけ出力にファイル名がないということが起こりうるので、ちゃんとしたスクリプトに組み込むなら/dev/nullつけとくほうが無難です。

$ echo *200901* | xargs grep ERROR /dev/null