까지/동시에 그리고 chain$?

까지/동시에 그리고 chain$?

종료 코드로 종료될 때까지 명령을 반복하고 싶었기 0때문에 다음을 시도했습니다.

$ while/until $?; do $command; done

하지만 and not 과 until/while같은 부울 값만 허용하는 것 같습니다 .true/false0/1

제가 비슷한 것이나 뭔가를 놓쳤나요 [[ ]]?

답변1

while키워드 에는until주문하다그들의 주장으로. 명령이 "성공"을 나타내는 0 종료 상태를 반환하면 while루프 본문 내의 명령이 실행 until되고아니요루프 본문 내에서 명령을 실행합니다.

while귀하의 코드는 and untilwith $?(가장 최근 명령의 종료 상태)를 명령으로 사용하는 것으로 보입니다 . 이름이 정수인 명령이 시스템에 없으면 작동하지 않습니다. 무엇회의작업은 test명령을 사용하여 와 비교하는 것입니다 0.

until test "$?" -eq 0; do some-command; done

또는 약어를 사용 test하여

until [ "$?" -eq 0 ]; do some-command; done

이제 문제는 분명히 $?루프에 들어갈 때 0이 되어 루프가 한 번 실행되는 것을 방지한다는 것입니다. 명령 자체가 종료 상태를 or 에 직접 제공하도록 하는 것이 while더 합리적입니다 until(예를 들어 루프 전에 호출하여 0이 아닌 값으로 초기화하려는 경우가 아닌 이상 $?이상해 보입니다).false

표준 POSIX 사용(Bourne은 아니지만 지금은 중요하지 않음) 셸 구문:

while ! some-command; do continue; done

또는 (Bourne 및 POSIX),

until some-command; do continue; done

두 명령 모두 some-command0 종료 상태("성공")가 반환될 때까지 실행됩니다. 각 반복마다 continue루프 본문 내부의 키워드를 실행합니다. 실행은 continue루프의 다음 반복으로 즉시 점프하지만 이를 예를 들어 sleep 5각 반복에서 짧은 지연을 갖거나 :아무 작업도 수행하지 않는 데 사용할 수 있습니다.

또 다른 변형은끝없는명령이 성공하면 종료되는 루프:

while true; do some-command && break; done

또는 좀 더 장황하고 가독성을 높이기 위해 공백을 추가하려면

while true; do
    if some-command; then
        break
    fi
done

당신이 정말로 유일한 시간필요$?다음과 같이 일정 기간 동안 값을 추적해야 할 때 사용 됩니다.

somefunction () {
    grep -q 'pattern' file
    ret=$?
    
    if [ "$ret" -ne 0 ]; then
        printf 'grep failed with exit code %s\n' "$ret"
    fi >&2
    
    return "$ret"
}

위 코드에서는 $?테스트에 의해 종료 상태가 재설정되며 [ "$ret" -ne 0 ]이를 별도의 변수에 저장하지 않으면 해당 값을 인쇄하거나 함수에서 반환할 수 없습니다.


또 다른 지적해야 할 점은 당신이 사용하는 것 같다는 것입니다, $command(따옴표 없음)을 명령으로 사용하세요. 이것은 ~이 될 것이다훨씬 낫다변수에 저장된 명령을 실행하려면 배열을 사용하십시오.

thecommand=( awk -F ',' 'BEGIN { "uptime" | getline; split($4,a,": "); if (a[2] > 5) exit 1 }' )

while ! "${thecommand[@]}"; do sleep 5; done

(이 예제 코드는 1분 평균 시스템 로드가 5 미만으로 떨어질 때까지 5초마다 대기합니다.)

배열을 사용하고 확장을 참조함으로써 "${thecommand[@]}"쉘이 문자열을 단어로 분할하고 각 단어에 파일 이름 와일드카드를 적용하는 방법에 대해 걱정할 필요 없이 명령을 실행할 수 있습니다.

당신은 또한 볼 수 있습니다변수에 저장된 명령을 어떻게 실행할 수 있나요?귀하의 질문에 대한 추가 정보입니다.

답변2

다음을 수행할 수 있습니다.

false; while [[ $? -ne 0 ]]; do
  command
done

여기서는 false처음에 0이 아닌 값으로 설정되어 $?루프가 적어도 한 번 실행될 수 있습니다. 그러면 주어진 명령은 0 종료 상태로 종료될 때까지 루프에서 실행됩니다.

관련 정보