web-dev-qa-db-ja.com

特定の受信者に関するすべてのメッセージの詳細をsendmailログで検索するには、どのコマンドを使用できますか。

CENTOS 5.x | Sendmail

ときどき、sendmail配信ログを検索して、見つからないメッセージに何が起こったかを調べる必要があります。これには通常、2つ(またはそれ以上)のステップが含まれます。

ステップ1:/ var/log/maillogでユーザーのメールアドレスを検索します。例grep -i "[email protected]"/var/log/maillog

これは通常、次のようなものを返します。

  Jan 11 07:43:34 server-example sendmail[12732]: p937blksdh3: to=<[email protected]>, delay=00:00:00, xdelay=00:00:00, mailer=esmtp, pri=102537, relay=mta.recipientdomain.com. [12.34.56.78], dsn=5.7.1, stat=Service unavailable

ステップ2:次に、一意のメッセージ名(この場合はp937blksdh3)を取得して検索します。例:grep -i p937blksdh3/var/log/maillog

ステップ1と2を1つのライナーに組み合わせて、他のIDに対して同じ検索を自動的に実行させたい。したがって、単一のコマンドで、次のようにしたいと思います。

  1. Sendmailメールログで特定の文字列を検索します。
  2. 電子メールのメッセージID(上記の例では、これはp937blksdh3)を特定します。 (私は推測していますawk '{print $}'が使用されますか?)
  3. 同じログを検索しますが、代わりにメッセージIDを検索します(上記の例では、基本的にgrep -i p937blksdh3/var/log/maillog
  4. 手順3の結果を出力します。これを他のメッセージIDに対して繰り返します。
4
Mike B

これに似たことができます。

for i in `grep -i "[email protected]" /var/log/maillog | awk '{print $5}'`; do grep -i $i /var/log/maillog; done

これにより、探しているユーザーの行がgrepさ​​れ、その行の5番目の項目が選択されます(スペースiircで区切られています)。次に、そのリストの各メッセージIDについて、メッセージIDを含む行をgrepします。

メッセージIDの末尾から:を削除したい場合は、_ [in for grep -i "[email protected]" /var/log/maillog | awk '{print $5}' | sed 's/\://; grep -i $ i/var/log/maillog;を実行します。できた

お役に立てば幸いです。

7
Harry

これはハリーの答えを洗練させたものです。

まず、awkはgrepのようなパターンマッチを実行できるため、最初のgrepをスキップできます。また、重複する可能性があるため、sort -uを使用してそれらを削除できます。

for i in `awk '/[email protected]/ {print $6}' /var/log/maillog | sort -u `; do grep -i $i /var/log/maillog; done

このバージョンでは、メールログの2つのパスを使用します。

awk '/[email protected]/ {print $6}' /var/log/maillog | sort -u > /tmp/message-ids.list
grep -f /tmp/message-ids.list /var/log/maillog

最初のバージョンでは、forループはmail.logを介してgrepを実行し、ログで見つかったメッセージIDの数と同じ数を探します。 2番目のバージョンでは、grepはメッセージIDのリストをフィルターとして使用し、ログファイルを1回だけ処理します。これは、大きなログファイルの場合により効率的です。

2
KIsmay

これは特定の問題に対する直接的な回答ではありませんが(Harry answered すでに問題です)、そのような情報が頻繁に必要な場合は、事前に計画を立てることを検討してください。 MIMEDefang をインストールし、次に filter_recipient ルーチンに、必要なすべての情報を最適な形式で記録させます。

2
adamo

AWKはgrepのジョブを実行できるため、grepawkにパイプする理由はありません。 forは標準入力のパターンを受け入れることができるため、grepループを使用する理由もありません。

awk '/[email protected]/ {print $6}' /var/log/maillog | sort -u  | grep -i -f - /var/log/maillog

これをさらに変更して、sort -u(実際には、sortは不要です-uniqを使用できます)

awk '/[email protected]/ {addr[$6]} END {for (a in addr) {print addr[a]}}' /var/log/maillog | grep -i -f - /var/log/maillog

それらの両方(および他の回答)は、ログファイルを2回以上パスで検索します。次のワンパステクニックの方が高速であるかどうか(そして、PerlまたはPythonを使用しても高速であるかどうか)は興味深いでしょう。

awk -v addr='[email protected]' '$0 ~ addr {
         ids[$6]
     }
     {
         for (id in ids) {
             if ($0 ~ "^" ids[id] "$") {
                 print
             }
         }
     }
     $NF == "Completed" {
         delete ids[$1]
     }' /var/log/maillog

私はそのコードをテストしていません。特に「完了」ログエントリが見つかったときにIDを削除するセクションで、フィールド番号を調整する必要がある場合があります。簡単にワンライナー化できます。