私はスクリプトの世界に不慣れで、現在、スクリプトを使用して、管理しているsanデバイスのヘルスチェックを実行しています。
スクリプトは単純で、コマンドの出力をリモートデバイスからローカルホストへの現在のファイルにリダイレクトします。次に、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 :)
これまでのところ、電子メール部分は機能しています(diff
コマンドとの違いがある場合にのみ電子メールを受け取ります)。しかし、私が今受け取っている電子メールは、テストが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行ずつ表示する必要があります。助言がありますか?
問題は、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つです。 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
したがって、それ自体が便利なように思えますが、コマンドが正常に実行されたかどうかを判断できます。ただし、これに対処する方法はありません。それでは、論理演算子を見てみましょう。
もう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と同じように真の論理演算子であるため、構造体のタイプには1つの問題があります。これらについては bashpitfallsのWebサイト で読むことができます。
したがって、これは有効なアプローチのようです。しかし、おそらく別の方法があります。読み続けます。
3番目の方法は、if/thenブロックを参加させてmail
プログラムを実行することです。コマンドが1分前に述べた論理演算子に関連している場合、それらは条件付きと呼ばれます。
注:また、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
更新されたスクリプトを確認するには、次の変更を行う必要があります。
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行で表示されるという問題は、\n
などの特殊文字を展開するように指示せずにecho
を使用したことが原因でした。例えば:
$ echo "oneline\ntwoline"
oneline\ntwoline
$ echo -e "oneline\ntwoline"
oneline
twoline
私が行ったもう1つの変更は、diff
の実行方法にありました。これは機能に悪い影響を与えることはありませんでしたが、バッククォート(\
.. `) has been deprecated in favor of this notation,
$(...)`。これらには、コマンドを内部にネストできるという追加の利点があります。次のような他のコマンド:
$ myvar=$(echo "good + $(echo bye)")
$ echo $myvar
good + bye
私はここで同じことをしていますが、Subversionで設定を保存しているので、通常のdiffの代わりにsvndiffを実行します。私のコードは:
diff=$(svn di)
if [ -n "$diff" ]
then
svn di | mail -s subject recipient
fi