プロが教える店舗&オフィスのセキュリティ対策術

お世話になります。
まず、下記のスクリプトをご確認ください。

if [ ! -f ${E_FILE} -o -f ${E_FILE} -a `grep -c 'ERROR' ${E_FILE}` -ne 0 ] ; then

上記条件文は次のような論理解釈で作成しました。
(${E_FILE}というファイルが存在しない) or 
(${E_FILE}というファイルが存在する and ファイル内に'ERROR'という文字列が存在する)

これを実行すると: too many argumentsというエラーが返ってきます。
原因をご存知の方がいればご教示いただきたく存じます。
よろしくお願いいたします。

A 回答 (2件)

原因は${E_FILE}が存在しないからです。


まず、下記の部分についてどのように実行されるとお考えでしょうか?

if [ ! -f ${E_FILE} -o -f ${E_FILE} -a `grep -c 'ERROR' ${E_FILE}` -ne 0 ] ; then

おそらく、以下のように考えておられるのではないでしょうか?
1.test ! -f ${E_FILE}
2.これがFALSEなら test -f ${E_FILE}
3.これがTRUEならgrep -c 'ERROR' ${E_FILE}
4.test (3の結果) -ne 0

しかし、残念ながら実際には、
1.grep -c 'ERROR' ${E_FILE} →ファイルが存在しないのでエラー(標準出力はなし)
2.test ! -f ${E_FILE} -o -f ${E_FILE} -a -ne 0

2の部分で-a -ne 0の部分が文法エラーです。

理由は2が1つのコマンドとして解釈され、その前に``の部分が解釈されるからです。


されたいことを実現するには下記のように書くべきです。

if [ ! -f ${E_FILE} ] || [ -f ${E_FILE} -a `grep -c 'ERROR' ${E_FILE}` -ne 0 ]; then

さらに言えば、[ ! -f ${E_FILE} ]がFALSEならtest -f ${E_FILE}は必ずTRUEなので、
下記のように簡略化できます。

if [ ! -f ${E_FILE} ] || [ `grep -c 'ERROR' ${E_FILE}` -ne 0 ]; then


余談ですが書かれているコードをきっちりと書くならこんな感じ。

if test ! -f "${E_FILE}" || grep 'ERROR' "${E_FILE}"` > /dev/null; then

・例えば上記のようなことがあるから、-a、-oはあまり使わないほうが良い
(さらに、-a、-oは評価順序に関する規定が曖昧だから、右側から評価されても文句は言えない)
・変数はスペースが入ってきた場合を考慮してダブルクォーテーションで括る
・`grep -c ~` -ne 0はgrep ~ > /dev/nullで置き換えが可能
・[]よりもtestを使う。(Autoconfのドキュメントにある移植性の高いプログラムを書くためのガイドライン)
    • good
    • 0
この回答へのお礼

ご回答ありがとうございます。
頂いた方法で無事解決することができました。
またよろしくお願いいたします。

お礼日時:2012/11/13 13:49

${E_FILE} というファイルが存在しないとき、



grep -c ERROR ${E_FILE}

は、エラーメッセージを出して、標準出力への書き出しはありません。従って、

if [ ! -f ${E_FILE} -o -f ${E_FILE} -a -ne 0 ]

となり、"[" コマンド の構文エラーになります。

そういうときは普通は、ファイルがあるときだけgrepを実行するようにします。

if [ ! -f ${E_FILE} ] || [ `grep -c ERROR ${E_FILE}` -ne 0 ]

さらに普通には、

if [ ! -f ${E_FILE} ] || grep ERROR ${E_FILE} >/dev/null
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!