Bashの「if」ステートメントの「and」演算子


168

単純なBashスクリプトを作成して、Webサイトがダウンしているかどうか、および何らかの理由で「and」演算子が機能していないかどうかを確認しようとしています。

#!/usr/bin/env bash

WEBSITE=domain.com
SUBJECT="$WEBSITE DOWN!"
EMAILID="an@email.com"
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" ]]

また、いつ使用するかアドバイスしてください。

  • 単一および二重角括弧
  • 括弧


3
「うまくいかない」ことをもっと正確に教えてください。特定のエラーメッセージがありますか、それとも期待される出力が得られませんか?
Julien Vivenot

実際には「単項演算子が期待されています」を受け取っていたため、引用が役立つように見えます
HTF

-a重複があります。Bourneシェルスタイルのtestコマンド(別名[)と一緒に使用すると、を意味しandます。条件式として使用すると、ファイルが存在するかどうかをテストします。はい、わかりにくいので、避けた方がいいでしょう。
cdarke

このアウトをチェックしてください:theunixshell.blogspot.com/2013/05/...
ビジェイ

回答:


254

${STATUS}空でない限り、あなたが持っているものは動作するはずです。おそらくそれが良いでしょう:

if ! [ "${STATUS}" -eq 200 ] 2> /dev/null && [ "${STRING}" != "${VALUE}" ]; then

または

if [ "${STATUS}" != 200 ] && [ "${STRING}" != "${VALUE}" ]; then

スクリプトの問題点を正確に示していないので、言うのは難しいです。

個人的な意見:決して使用しないでください[[。重要なエラーメッセージを抑制し、別のシェルに移植できません。


2
STATUSが空の場合、@ HTFのコードはで失敗し-ne: unary operator expectedます。あなたの場合、それは失敗しinteger expression expectedますね?
Julien Vivenot 2012年

1
という事は承知しています。しかし、$STATUS空である可能性のある問題を強調表示し、解決策(引用)を提案します。あなたの解決策はまだ空STATUSで失敗します、それは私が意味するすべてです。
Julien Vivenot

1
@jvivenotポイントがあります。。(あなたのコメントを編集した前に、あなたのコメントは、単に読んだときにあなたのコメントへの私の応答は、作られた「コードを...失敗しただろう」シンプルなソリューションを使用することです${STATUS:-0"ウィル編集。。
ウィリアムPursell

編集はまだ機能しません。たとえば、STATUS=; [ $STATUS -ne 13 ] 2>/dev/null && echo fooは出力しますがfoo、出力しません(空は13とは異なります)。あなたが最初に提案したものは、${STATUS:-0}はるかに良く見えます。
Julien Vivenot 2012年

@jvivenotを使用${STATUS:-0}すると失敗しますSTATUS=fooが、! [ "$STATUS" -eq 200 ] 2> /dev/null && echo foo機能します。IMO、ただし、避け-eqて使用すること!=をお勧めします。
ウィリアムパーセル

28

これを試して:

if [ $STATUS -ne 200 -a "$STRING" != "$VALUE" ]; then

私のために働いた。複数の方法があると思いますが、今のところこれで満足しています。
Kushal Ashok

27

これを試して:

if [ ${STATUS} -ne 100 -a "${STRING}" = "${VALUE}" ]

または

if [ ${STATUS} -ne 100 ] && [ "${STRING}" = "${VALUE}" ]

さらに、最もクリーンな例
Pawel Cioch

12

見積もり:

「-a」演算子も機能しません。

if [$ STATUS -ne 200] -a [["$ STRING"!= "$ VALUE"]]

より精巧な説明については:[]バッシュは、単語を予約されていません。ifキーワード紹介Aの条件付きジョブによって評価される(ジョブの戻り値がある場合は、条件が真である0か、そうでない場合はfalse)。

ささいなテストのために、testプログラムがあります(man test)。

のような一部の行がif test -f filename; then foo bar; fi煩わしいので、ほとんどのシステム[で、実際にはtestプログラムへのシンボリックリンクにすぎないプログラムが呼び出されます。testがとして呼び出された場合、最後の位置引数として[追加する必要があり]ます。

したがってif test -f filename、(生成されたプロセスに関して)基本的にはと同じif [ -f filename ]です。どちらの場合もtestプログラムが開始され、両方のプロセスは同じように動作するはずです。

ここにあなたの間違いif [ $STATUS -ne 200 ] -a [[ "$STRING" != "$VALUE" ]]があります:if+いくつかのジョブに解析され、そのジョブはifそれ自体を除くすべてのものです。ジョブは単純なコマンドのみです(Bashは単一のプロセスになる結果を意味します)。つまり、最初の単語([)がコマンドで、残りがその位置引数です。最初の後に残りの引数があります]

また、[[実際にはBashキーワードではありませんが、この場合、コマンドの前にないため、通常のコマンド引数としてのみ解析されます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.