diffコマンドがdiffを提供したときにのみ電子メールを送信するようにスクリプトを構成します。

diffコマンドがdiffを提供したときにのみ電子メールを送信するようにスクリプトを構成します。

私はスクリプトの世界が初めてで、現在私が管理しているSANデバイスでヘルスチェックを実行するためにスクリプトを使用しています。

スクリプトは簡単で、リモートデバイスからのコマンド出力を現在のファイルのローカルホストにリダイレクトします。次に、diffコマンドを使用して現在のファイルと参照ファイルの出力を比較し、違いに関する電子メール通知を受け取ります。

しかし、現在私が経験している問題は、スクリプトを実行するたびにスクリプトの実行後に電子メールが来る、つまり比較結果に違いがないにもかかわらず、スクリプトの実行時に空の電子メールが表示されることです。

これは自動化されたヘルスチェックの実行に関連しているため、毎日空白の電子メールを受信するのは面倒です。 diffにdiffが表示されず、diffがあり、diffが表示されている場合にのみ電子メールを受信しないようにdiffを調整したり、より多くのコードを追加する方法はありますか?

現在のスクリプト

### saves output of command switchshow in a file on local host
ssh user@ip_of_switch switchshow > switchshow_results

### Compares current output to reference file and mails the difference
diff switchshow_reference switchshow_results \
    | mail -s device_PORT_ERROR email_recipient

追加情報が必要な場合はお知らせください。


助けと詳細な説明をありがとうSlm :)

これまで、Eメール部分が機能しています(diffコマンドと違いがある場合にのみEメールを受け取ります)。しかし、今私が受け取るEメールにはテストが1つの長い文字列にリンクされているので、見た目にも良くなく、受信者もわかりにくいです。

私の現在のスクリプトは以下に貼り付けられています。

ssh test@ip_of_device switchshow > switchshow_results

variable=`diff switchshow_reference switchshow_results`

if [[ $variable -eq 0 ]]    
then    
  echo $"nothing"    
else    
  echo $variable | mail -s switch_HARDWARE_CHECK  recipeint_email_address    
fi

上記のスクリプトの出力は空で、diffコマンドで違いが見つからない場合は電子メールが届きません。ただしdiff、コマンドが違いを発見した場合は、下に貼り付けた電子メールを受け取ります。

16c16 < 0 0 010000 id N4 Online FC F-Port 1 N Port + 1 NPIV public --- > 0 0 010000 id N4 No_Light FC F-Port 1 N Port + 1 NPIV public 26c26 < 10 10 010a00 id N4 Online FC F-Port 1 N Port + 1 NPIV public --- > 10 10 010a00 id N4 No_Light FC F-Port 1 N Port + 1 NPIV public 29c29 < 13 13 010d00 id N4 Online FC F-Port 50:06:01:67:3b:20:23:0a --- > 13 13 010d00 id N4 No_Light FC F-Port 50:06:01:67:3b:20:23:0a

理想的には、電子メールで次のように表示する必要があります。

16c16 < 0 0 010000 id N4 Online FC F-Port 1 N Port + 1 NPIV public --- > 0 0 010000 id N4 No_Light FC F-Port 1 N Port + 1 NPIV public 

26c26 < 10 10 010a00 id N4 Online FC F-Port 1 N Port + 1 NPIV public --- > 10 10 010a00 id N4 No_Light FC F-Port 1 N Port + 1 NPIV public

29c29 < 13 13 010d00 id N4 Online FC F-Port 50:06:01:67:3b:20:23:0a --- > 13 13 010d00 id N4 No_Light FC F-Port 50:06:01:67:3b:20:23:0a

出力は電子メールで一度に1行ずつ表示する必要があります。どんな提案がありますか?

ベストアンサー1

問題は実行に使用するコマンドですdiff。このmailコマンドは、違いがあるかどうかに関係なく、結果を実行するたびにトリガーされます。

はい

ここでは、2つのechoコマンドを使用して、次のように2つのファイルをシミュレートします。

$ diff <(echo 1) <(echo 2)
1c1
< 1
---
> 2

大丈夫に見えますが、echoコマンドが同じであればどうなりますか?

$ diff <(echo 1) <(echo 1)
$ 

まあ、それは問題ではないようですね。コマンドの出力をdiff別のコマンドにパイプするとechoどうなりますか?

$ diff <(echo 1) <(echo 1) | echo "hi"
hi

diffパイプから他のコマンドへの空の出力でも、そのコマンドが実行されるようにトリガします。

それでは、正しいアプローチは何ですか?

あなたが本当にやりたいことは2つのうちの1つです。コマンドの状態を確認するか、and(and)や演算子(または演算子)diffなどの論理演算子を使用してください。&&||

状態

ほとんどのコマンドは実行時にステータスを返します。通常、0 または 1 は、ジョブの成功または失敗を示すために使用されます。 Bash で状態変数を分析してdiff状態を表示できます。$?

diffファイルが一致した場合は0を返します。

$ diff <(echo 1) <(echo 1)
$ echo $?
0

diffファイルが一致しない場合は1を返します。

$ diff <(echo 1) <(echo 2)
1c1
< 1
---
> 2

$ echo $?
1

したがって、それ自体は役に立ち、コマンドが正常に実行されたかどうかがわかります。しかし、私たちがそれについて何もする方法はありません。それでは論理演算子を見てみましょう。

論理演算子

別のアプローチは、最初のコマンドが成功した場合に2番目のコマンドが実行されるように2つのコマンドを変更することです。代わりに、最初のコマンドが失敗した場合は、代替演算子を使用して2番目のコマンドを実行できます。

はい

様々な火溶論

$ diff <(echo 1) <(echo 2) || echo "they're different"
1c1
< 1
---
> 2
they're different

同じプラグマ

$ diff <(echo 1) <(echo 1) && echo "they're the same"
they're the same

メモ:この方法を使用する場合は注意してください。上記は実際にはif .. then .. elseのような論理演算子なので、構造体型に問題があります。することができますbashpitfallsのウェブサイト

したがって、これは有効なアプローチのようです。しかし、たぶん別の方法があるかもしれません。読んでください。

もしそうなら、そうでなければ

3番目の方法は、if / thenブロックを使用してプログラムを実行することですmail。 if/then コマンドは、前述の論理演算子に関連しており、条件文と呼ばれます。

メモ:そしてdiff、実際にはif / then文のための最高のツールではありません。cmpステータスのみを返すコマンドを使用することをお勧めします。それでは、アップグレードもしましょう。

はい

同じ

$ cmp -s <(echo 1) <(echo 1)
$ echo $?
0

その他

$ cmp -s <(echo 2) <(echo 1)
$ echo $?
1

これをif / thenブロックに拡張すると、次のようになります。

$ if cmp -s <(echo 2) <(echo 1);then echo "same"; else echo "different";fi
different

$ if cmp -s <(echo 1) <(echo 1);then echo "same"; else echo "different";fi
same

あなたの問題

その後、元の質問について次のようにすることができます。

if cmp -s switchshow_reference switchshow_results; then
  diff switchshow_reference switchshow_results \
     | mail -s device_PORT_ERROR email_recipient
fi

アップデート#1

更新されたスクリプトを表示するときは、次のように変更する必要があります。

ssh test@ip_of_device switchshow > switchshow_results

variable=$(diff switchshow_reference switchshow_results)

if [[ $variable -eq 0 ]]    
then    
  echo $"nothing"
else    
  echo -n "$variable" | mail -s switch_HARDWARE_CHECK  recipeint_email_address

fi

出力が1行で表示される問題は、echo特殊文字を拡張せずに使用したためです\n。たとえば、次のようになります。

$ echo "oneline\ntwoline"
oneline\ntwoline

$ echo -e "oneline\ntwoline"
oneline
twoline

私が修正したもう一つの方法はdiff機能に悪影響を与えませんが、バックティック( \..` ) has been deprecated in favor of this notation,$(...)` )です。

$ myvar=$(echo "good + $(echo bye)")
$ echo $myvar
good + bye

おすすめ記事