シェルスクリプト逆引き大全 サポート情報 Tips 279

UNIXシェルスクリプト逆引き大全 333の極意

[サポート情報] Tips 279 電子メールを送信する

mail_send.shのバグ [2004/10/15修正]

chap08/mail_send.shに次のようなバグを見つけました。最新版のアーカイブ及び第2刷では修正されています。

現象

入力メッセージに「From:」「Message-Id:」ヘッダが含まれている場合でも,新たに生成したヘッダを追加してしまいます。結果として,それらのヘッダが重複します。

原因

fixheader関数は,入力メッセージに「From:」「Message-Id:」ヘッダが含まれているかどうかを次のようにチェックしていました。

if echo "$header" | grep -qvi '^from:'; then
    #「From:」ヘッダを追加する処理
fi

ここで,「From:」ヘッダが見つからない場合に真,という意図でgrepの「-v」オプションを指定しているのですが,ここが誤りです。

-v」は「条件に一致しない行を探す」オプションなので,このコードでは「From:」ヘッダ以外の全ての行にマッチします。つまり,入力に「From:」が含まれていようとなかろうと,このgrepコマンドは常に真(終了コード0)を返し,新しいヘッダが追加されることになります。

厳密には,入力が1行のみの場合にはこのコードでも正しく動作します。でも,それでは電子メールとして意味がありません。

ここでは「From:」の場合のみを示しましたが,「Message-Id:」についても同様です。

対処

bashやPOSIX準拠の/bin/shを使っている場合,一番簡単な方法はコードを次のように修正することです。

if ! echo "$header" | grep -qi '^from:'; then
    #「From:」ヘッダを追加する処理
fi

ただし,「!」による条件の反転はサポートされていなかったり,バグがあることもありますので,移植性を重視する場合には次のように書く方が良いでしょう。

if echo "$header" | grep -qi '^from:'; then
    : #「:」は「何もしない」組み込みコマンド(終了コードは常に0)
else
    #「From:」ヘッダを追加する処理
fi

[戻る]