Bash의 "if"문에 대한 "and"연산자


168

웹 사이트가 다운되었는지 확인하고 어떤 이유로 "and"연산자가 작동하지 않는 간단한 Bash 스크립트를 만들려고합니다.

#!/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/…
Vijay

답변:


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

1
나는 이해. 그러나 $STATUS비어있을 수있는 문제를 강조 표시하고 해결책을 제시하십시오 (인용). 귀하의 솔루션은 여전히 ​​비어있는 상태로 실패합니다 STATUS.
Julien Vivenot

1
@jvivenot 포인트가 있습니다. . 당신이 ... "실패했을 코드를"A의 간단한 솔루션을 사용하는 것입니다 귀하의 의견은 단지 읽는 당신의 코멘트를 편집하기 전에 (귀하의 코멘트에 나의 응답이되었다 ${STATUS:-0".. 윌 편집
윌리엄 Pursell

편집이 여전히 작동하지 않습니다. 예를 들어 : STATUS=; [ $STATUS -ne 13 ] 2>/dev/null && echo foofoo비어 있지만 출력하지 않습니다 (빈은 13과 다릅니다). 처음 제안한 내용 ${STATUS:-0}이 훨씬 좋아 보입니다.
Julien Vivenot

@jvivenot if 사용 ${STATUS:-0}하면 실패 STATUS=foo하지만 ! [ "$STATUS" -eq 200 ] 2> /dev/null && echo foo작동합니다. 그러나 IMO는 피하고 -eq사용 하는 것이 좋습니다 !=.
William Pursell

28

이 시도:

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

나를 위해 일했다. 나는 두 가지 이상의 방법이있을 수 있다고 생각하지만 지금은 이것에 만족합니다.
Kushal Ashok

26

이 시도:

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

또는

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

더 깨끗한 예를 들어
Pawel Cioch

12

인용문:

"-a"연산자도 작동하지 않습니다 :

[$ STATUS -ne 200] -a [[ "$ STRING"! = "$ VALUE"]] 인 경우

보다 정교한 설명은 : []배쉬는 예약어되지 않습니다. if키워드를 소개하는 조건 작업에 의해 평가되어야한다 (작업의 반환 값 인 경우 조건은 사실 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.