Bash의 간단한 논리 연산자


256

몇 가지 변수가 있고 다음 조건을 확인하고 싶습니다 (단어로 작성된 다음 bash 스크립팅에서 실패한 시도).

if varA EQUALS 1 AND ( varB EQUALS "t1" OR varB EQUALS "t2" ) then 

do something

done.

그리고 실패한 시도에서 나는 다음을 생각해 냈습니다.

if (($varA == 1)) && ( (($varB == "t1")) || (($varC == "t2")) ); 
  then
    scale=0.05
  fi

답변:


682

실제로 작성한 것은 거의 효과가 있지만 (모든 변수가 숫자이면 작동 할 수는 있지만) 관용적 인 방법은 아닙니다.

  • (…)괄호는 서브 쉘을 나타냅니다 . 그 안에 들어있는 것은 다른 많은 언어와 같은 표현이 아닙니다. 외부 괄호와 마찬가지로 명령 목록입니다. 이러한 명령은 별도의 하위 프로세스에서 실행되므로 괄호 안에서 수행되는 리디렉션, 할당 등은 괄호 밖에서 영향을 미치지 않습니다.
    • 선도적 인 달러 기호, $(…)A는 명령 치환 이 괄호 안에 명령이고, 명령의 출력은 명령 행의 일부로 사용된다 (대체 따옴표 사이에하지 않는 한 추가 확장 후,하지만 그건 : 또 다른 이야기 ) .
  • { … }중괄호는 명령을 그룹화한다는 점에서 괄호와 비슷하지만 그룹화가 아닌 구문 분석에만 영향을 미칩니다. 이 프로그램 x=2; { x=4; }; echo $x은 4를 x=2; (x=4); echo $x인쇄 하는 반면 2를 인쇄합니다. (괄호는 닫을 때 괄호에는 공백과 세미콜론이 필요하지만 괄호는 필요하지 않습니다. 이는 구문상의 문제입니다.)
    • 선행 달러 기호를 사용하면 추가 확장을 통해 변수 값으로 확장${VAR} 되는 매개 변수 확장 이 있습니다.
  • ((…))이중 괄호 는 다른 프로그래밍 언어와 유사한 구문 으로 산술 명령어 , 즉 정수에 대한 계산을 둘러 쌉니다 . 이 구문은 주로 할당 및 조건부에서 사용됩니다.
    • 동일한 구문이 산술 표현식에 사용되며 표현식 $((…))의 정수 값으로 확장됩니다.
  • [[ … ]]이중 괄호는 조건식을 둘러 쌉니다 . 조건식은 대부분 변수가 비어 있는지 테스트하고 파일이 존재하는지 테스트 하는 등의 연산자를 기반으로 합니다. : 문자열 평등 사업자도 있습니다 (오른쪽이 패턴, 예를 들면 것을 조심 시험의 경우 와 시작 하면서 테스트하는 경우 정확히 ), 그리고 익숙한 , 그리고 부정, 결합 및 분리뿐만 아니라 그룹화 괄호에 대한 운영. 각 연산자 주위에 공백이 있어야하며 (예 : , not ), 괄호 안팎에 공백이나 문자가 있어야합니다 (예 : ,-n $variable-e $file"$string1" == "$string2"[[ $foo == a* ]]$fooa[[ $foo == "a*" ]]$fooa*!&&||[[ "$x" == "$y" ]][[ "$x"=="$y" ]];[[ -n $foo ]][[-n $foo]]).
  • [ … ]단일 괄호는 더 많은 기발한 (그러나 더 오래되고 더 휴대하기 쉬운) 조건식의 대체 형식입니다. 지금은 아무 것도 쓰지 마십시오. 스크립트가 포함 된 스크립트를 찾을 때 걱정하기 시작하십시오.

이것은 bash에서 테스트를 작성하는 관용적 방법입니다.

if [[ $varA == 1 && ($varB == "t1" || $varC == "t2") ]]; then

다른 쉘로 이식성이 필요한 경우 다음과 같이됩니다 (각 개별 테스트 주위에 추가 인용 부호와 별도의 괄호 세트 및 =ksh / bash / zsh ==변형이 아닌 기존 연산자 사용 ).

if [ "$varA" = 1 ] && { [ "$varB" = "t1" ] || [ "$varC" = "t2" ]; }; then

31
훌륭한 게시물, 대괄호 요약은 이상적입니다.
KomodoDave

10
==변수 할당과 비교를 구별하는 데 사용 하는 것이 좋습니다 (또한 =)
Will Sheppard

1
오, 나는 단일 (둥근) 괄호를 의미했습니다. 혼란을 드려 죄송합니다. 의 사람들이 [[ $varA = 1 && ($varB = "t1" || $varC = "t2") ]]첫 번째 글 머리가 명시 적으로 말한다 있지만 하위 프로세스를 시작하지 않습니다 : "안에 무엇이 [괄호] 표현하지 않는 다른 언어처럼"-하지만 그것은 확실히 여기! 아마도 경험 많은 bash wiz에게는 분명하지만 즉시 나에게는 그렇지 않습니다. 큰 괄호 안의 표현식이 아닌 단일 괄호 if 명령문에 사용할 있기 때문에 혼동이 발생할 수 있습니다 .
피터-모니카 복원 복원

2
@protagonist ==는 실제로 "관용적"이 아닙니다 =. 그것들은 같은 의미를 갖지만, ==bash 및 zsh에서도 사용 가능한 ksh 변형 =이며 이식성이 있습니다. 을 사용 ==하면 실제로 이점 이 없으며 일반 sh에서는 작동하지 않습니다.
Gilles 'SO- 악마 그만해'

2
@WillSheppard 비교와 할당 사이에는 이미 다른 많은 차이점이 있습니다. 비교는 대괄호 안에 있고 할당은 그렇지 않습니다. 비교는 연산자 주위에 공백이 있고 할당은 그렇지 않습니다. 할당에는 왼쪽에 변수 이름이 있고 비교에는 왼쪽에 변수 이름처럼 보이는 것이 거의 없으며 어쨌든 따옴표를 넣을 수 있습니다. 원한다면 ==내부 [[ … ]]에 글을 쓸 수 있지만 =작업 할 수 있다는 이점이 [ … ]있으므로 사용 습관을 들이지 않는 것이 좋습니다 ==.
질 'SO-정지 존재 악마'

34

아주 근접한

if [[ $varA -eq 1 ]] && [[ $varB == 't1' || $varC == 't2' ]]; 
  then 
    scale=0.05
  fi

작동해야합니다.

그것을 분해

[[ $varA -eq 1 ]] 

다음과 같이 정수 비교입니다.

$varB == 't1'

문자열 비교입니다. 그렇지 않으면 비교를 올바르게 그룹화합니다.

이중 대괄호는 조건식을 구분합니다. 그리고 다음 주제에 대해 잘 읽어야합니다. "(IBM) Demystify test, [, [[, ((및 if-then-else")


확인하기 : 인용 't1'은 불필요합니다. 이중 괄호 안에 산술 명령어는 달리, 어디 때문에 t1변수가 될 것입니다, t1두 배의 조건식에 괄호 단지 리터럴 문자열입니다. 즉, [[ $varB == 't1' ]]와 정확히 동일 [[ $varB == t1 ]]합니까?
피터-복원 모니카

6

휴대 성이 뛰어난 버전 (레거시 bourne 쉘까지) :

if [ "$varA" = 1 -a \( "$varB" = "t1" -o "$varB" = "t2" \) ]
then    do-something
fi

이것은 [쉘 특성에 관계없이 최대 하나의 하위 프로세스 (프로세스 ) 만 실행하는 추가 품질을 갖습니다 .

교체 =-eq변수는 숫자 값을 포함하는 경우, 예를 들어,

  • 3 -eq 03 사실이지만
  • 3 = 03거짓입니다. (문자열 비교)

3

다음은 if-then-else 문의 짧은 버전에 대한 코드입니다.

( [ $a -eq 1 ] || [ $b -eq 2 ] ) && echo "ok" || echo "nok"

다음에주의하십시오.

  1. ||&&피연산자 경우 내부 상태 (즉, 둥근 괄호) 논리적 피연산자 (및 / 또는) 아르

  2. ||&&피연산자 외부 조건이라면 / 다른 의미

실제로 성명서는 다음과 같이 말합니다.

(a = 1 또는 b = 2) 인 경우 "ok", 그렇지 않으면 "nok"


괄호 ( ... )는 서브 쉘을 작성합니다. { ... }대신 중괄호를 사용하고 싶을 수도 있습니다 . 서브 쉘에서 생성 된 상태는 호출자에게 보이지 않습니다.
클린트 Pachl

0
if ([ $NUM1 == 1 ] || [ $NUM2 == 1 ]) && [ -z "$STR" ]
then
    echo STR is empty but should have a value.
fi
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.