ウェブサイトがダウンしているかどうかを確認するための簡単な Bash スクリプトを作成しようとしていますが、何らかの理由で「and」演算子が機能しません。
#!/usr/bin/env bash
WEBSITE=domain.example
SUBJECT="$WEBSITE DOWN!"
EMAILID="[email protected]"
STATUS=$(curl -sI $WEBSITE | awk '/HTTP\/1.1/ { print $2 }')
STRING=$(curl -s $WEBSITE | grep -o "string_to_search")
VALUE="string_to_search"
if [ $STATUS -ne 200 ] && [[ "$STRING" != "$VALUE" ]]; then
echo "Website: $WEBSITE is down, status code: '$STATUS' - $(date)" | mail -s "$SUBJECT" $EMAILID
fi
「-a」演算子も機能しません。
if [ $STATUS -ne 200 ] -a [[ "$STRING" != "$VALUE" ]]
以下の項目をいつ使用すればよいかアドバイスをお願いします。
- 一重角括弧と二重角括弧
- 括弧
?
ベストアンサー1
$STATUS
が空の文字列に展開される場合、if [ $STATUS -ne 200 ]
は と同等であるため無効となりif [ -ne 200 ]
、「-ne: 単項演算子が必要です」のようなエラーが発生します。
コマンド
if [ $STATUS -ne 200 ] -a [[ "$STRING" != "$VALUE" ]];
は、と をコマンドに引数として$STATUS
渡していますが、最後の引数がリテラル文字列 である必要があるため、の展開に関係なく無効です。次のようにする方がおそらくよいでしょう。[[
]]
[
[
]
if ! [ "${STATUS}" -eq 200 ] 2> /dev/null && [ "${STRING}" != "${VALUE}" ]; then ...
または
if [ "${STATUS}" != 200 ] && [ "${STRING}" != "${VALUE}" ]; then ...
これらの各コマンドでは、は、必要に応じ]
て の呼び出しに対する最後の引数です[
。シェルは&&
、と をコマンド;
を終了するトークンとして解析しますが、 、、[
などの文字列は、シェルがコマンドに渡す単なる文字列です。(最初のケースでは、シェルは をリダイレクト演算子として扱うため、これらの文字列は に引数として渡されません)。を の引数としてブールANDとして使用することは悪い習慣とみなされ、避けるべきであることに注意してください。-a
[[
]]
2> /dev/null
[
-a
[
[
と は非常に異なりますが、と[[
の唯一の違いは、 は最終引数が である必要があり、は ではないことです。(別の違いは、 は組み込みであるが はそうではないということであり、遠い昔には、一部のシェルに が組み込みとして があり、 whileが常に の呼び出しであった時代があったかもしれませんが、おそらく何十年もの間、一般的なシェルではそのような状況ではなかったでしょう)。別の合理的な解決策は次のとおりです。[
test
[
]
test
[
test
[
test
/bin/test
if test "${STATUS}" != 200 && test "${STRING}" != "${VALUE}"; then ...
個人的な意見: は絶対に使用しないでください[[
。重要なエラー メッセージが抑制され、異なるシェルに移植できません。また、この質問の存在からもわかるように、 は混乱を招きます。ここでの混乱はシェルの文法と の不明瞭な動作によって引き起こされていると主張する人もいるでしょうし[
、私も同意します。も混乱を招きます。と の両方を避け、常に を使用すると、多く[
の混乱を防ぐことができます。[[
[
test