
私はスクリプトの世界が初めてで、現在私が管理している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
答え2
ここでも同じことをしていますが、構成を保存するためにSubversionを使用しているので、通常のdiffの代わりにsvn diffを実行します。私のコードは次のとおりです
diff=$(svn di)
if [ -n "$diff" ]
then
svn di | mail -s subject recipient
fi