bash 쉘의 여러 줄에 조건이있는 경우


19

인수를 가져 와서 필요한 경우 무언가를 수행하는 bash 쉘 함수가 있습니다.

do_somthing() {
  if [need to do something on $1]
  then
    do it
    return 0
  else
    return 1
  fi
}

여러 인수를 사용 하여이 메소드를 호출하고 하나 이상이 성공했는지 확인하고 싶습니다.

나는 다음과 같은 것을 시도했다 :

if [ do_something "arg1" ||
     do_something "arg2" ||
     do_something "arg3" ]
then
  echo "OK"
else
  echo "NOT OK"
fi

그에 대한 올바른 구문은 무엇입니까?
편집
또한-첫 번째 조건이 true 인 경우에도 다른 모든 조건이 계속 평가되도록하고 싶습니다.

감사,


내 답변을 업데이트했습니다.
tectux

감사합니다. 예를 들어 주시겠습니까?
Itay

1
내 답변에 코드 예제를 추가했습니다.
tectux

답변:


7

먼저 명령을 실행 한 다음 적어도 하나가 성공했는지 확인하십시오.

#!/bin/bash

success=0
do_something arg1 && success=1
do_something arg2 && success=1
do_something arg3 && success=1

if ((success)); then
    printf 'Success! At least one of the three commands succeeded\n'
fi

3
이것은 당신이 성공시 0을 반환 do_something ..., 배쉬에서 작동하는 방법 조건문에 대한 몇 가지 설명을 제공 할 수 있다면 내가 드리겠습니다, 혼란,하지만 우리가 일에 성공을 업데이트 ... if ((success))보다는 뭔가 다른 평가 if success. 혼란스러워 :)
Itay

2
@Itay ((...))는 산술 명령입니다. 내부 결과가 0이 아닌 경우 true (0)를 리턴합니다. 내부 결과가 0이면 false (1)를 반환합니다. "성공"은 숫자를 포함 할 것으로 예상되는 변수로 취급됩니다. mywiki.wooledge.org/ArithmeticExpression
geirha

고마워요, 저를 혼란스럽게 한 부분은 0은 사실이고 1은 거짓이라는 것입니다. 일반적으로 반대입니다 :)
Itay

2
@Itay 예, 처음에는 혼란 스러울 수 있습니다. Bash는 "명령 기반"이라는 점에서 범용 언어와 다릅니다. 함수를 호출하지 않고 클래스와 메소드가 없으며 명령을 실행하며 명령의 종료 상태를 테스트합니다. 그리고 C, python, java, perl 등과 같은 언어보다 bash에서 명령을 실행하는 것이 훨씬 쉽습니다. 명령은 0으로 종료하여 성공을 알리고 1-255는 다양한 유형의 실패를 나타냅니다. (명령은 일반적으로 한 가지 방법으로 만 성공할 수 있지만 여러 가지 이유로 실패합니다)
geirha

2
이 솔루션은 일시적으로 비활성화하고 싶지 않은 라인을 주석 처리 할 수 ​​있다는 이점이 있습니다.
Josiah Yoder

31

백 슬래시를 사용하십시오.

if [ $(do_something "arg1") ] || \
   [ $(do_something "arg2") ] || \
   [ $(do_something "arg3") ]
then
  echo "OK"
else
  echo "NOT OK"
fi

편집하다

또한-첫 번째 조건이 true 인 경우에도 다른 모든 조건이 계속 평가되도록하고 싶습니다.

하나의 if 문에서만 불가능합니다. 대신 인수를 반복하고 별도로 평가하는 for 루프를 사용할 수 있습니다. 다음과 같은 것 :

do_something() {
  for x in "$@"
  do
    if [need to do something on $x]
    then
      do it
    else
      echo "no action required on $x"
    fi
  done
}

고마워, 시도-오류가 발생[: do_something: unary operator expected
Itay

각 평가를 자체 괄호 사이에 넣었습니까? 그래서 [ expr1 ] || [ expr2 ]대신 [ expr1 || expr2 ].
tectux

예, 나는 : (...
Itay

내 생각에 그것은 do_something "arg1"표현이 단항 해야하는 반면 두 가지 주장으로 해석됩니다. do_something "arg1"하나의 주장으로 평가할 수 있는 방법이 있습니까?
Itay

1
네가 옳아. 이것도 작동합니다 : if [ $(do_something "arg1") ].
tectux

5

올바른 구문은 다음과 같습니다.

if  do_something "arg1" || \
    do_something "arg2" || \
    do_something "arg3"
then
  echo "OK"
else
  echo "NOT OK"
fi

\ 다음 줄에서 명령이 계속되도록 쉘에 알리는 데 사용됩니다.

편집 : 나는 이것이 당신이 원하는 것을해야한다고 생각합니다 :

#!/bin/bash

do_something() {
  if [need to do something on $1]
  then
    do it
    echo "OK"
  else
    echo "NOT OK"
  fi
}

do_something "arg1"
do_something "arg2"
do_something "arg3"

감사합니다, 오류와 결과 :[: too many arguments
Itay

@Itay Answer가 업데이트되었습니다.
Eric Carvalho

질문을 업데이트-이것은 아직 최종 답변이 아닙니다 :(
Itay

-1

나는 선호한다:

if {
    do_something "arg1" ||
    do_something "arg2" ||
    do_something "arg3"
}; then
    echo "OK"
else
    echo "NOT OK"
fi

스크립트는 전혀 작동하지 않습니다. 첫 번째 테스트 매개 변수 후에는 \n문자를 생성 하므로 if명령문이 일부 오류를 생성하고 do_something명령 이름이 아니므로 더 많은 오류가 발생합니다.
damadam

나를 위해 그것은 zsh와 bash에서 작동합니다 .IF do_something는 물론 함수입니다. do_something기능 또는 명령이어야합니다. 그것은 생성 할 곳 또한 나는 볼 수 없습니다 \n... 결과를 울리는 후를 제외하고 문자를이 예상됩니다
Toxiro의
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.