linux - 커맨드라인 - 쉘 스크립트




a의 의미는 무엇입니까! 쉘에서 명령하기 전에? (2)

"!" "아닙니다"라는 의미이므로 명령 앞에 놓고 "$?"를 실행하면 그것은 1을 울릴 것입니다. 이는 성공을 의미하는 0 대신 실패했음을 의미합니다.

문제는 제목에 있습니다. 느낌표로 시작하는 쉘 명령 (쉘 스크립트의 일부)의 목적은 무엇입니까? 구체적인 예 :

foo.sh에서 :

#!/usr/bin/env bash
set -e
! docker stop foo
! docker rm -f foo
# ... other stuff

나는 공간이 없으면 감탄사 표시가 역사 대체물로 사용된다는 것을 알고 있습니다 ! <expression> man 페이지 에 따른 ! <expression> " expr이 거짓이면 참 "을 평가하는 데 사용할 수 있습니다. 그러나 나에게 의미가없는 예제 컨텍스트에서.


TL : 이것은 사용중인 특정 행에서 set -e 플래그를 우회하는 것입니다.

hek2mgl의 정확하고 유용한 대답에 추가 추가.

너는 :

set -e
! command

Bash 레퍼런스 매뉴얼 → 파이프 라인 설명 :

파이프 라인의 각 명령은 자체 하위 쉘에서 실행됩니다. 파이프 라인의 종료 상태는 파이프 라인에서 마지막 명령의 종료 상태 (...)입니다. 예약어 '!' 파이프 라인에 선행하는 경우 종료 상태는 위에서 설명한 종료 상태의 논리적 부정입니다 . 쉘은 값을 리턴하기 전에 파이프 라인의 모든 명령이 종료되기를 기다립니다.

이것은 의미합니다 ! 명령을 앞에두면 종료 상태가 무효화됩니다.

$ echo 23
23
$ echo $?
0
                # But
$ ! echo 23
23
$ echo $?
1

또는:

$ echo 23 && echo "true" || echo "fail"
23
true
$ ! echo 23 && echo "true" || echo "fail"
23
fail

종료 상태는 다양한 방법으로 유용합니다. 스크립트에서 set -e 와 함께 사용하면 명령이 0이 아닌 상태를 반환 할 때마다 스크립트가 종료됩니다.

따라서 다음과 같은 경우 :

set -e
command1
command2

command1 이 0이 아닌 상태를 반환하면 스크립트가 완료되고 command2 진행하지 않습니다.

그러나 4.3.1에 설명 된 흥미로운 점이 있습니다 . Set Builtin :

-이자형

단일 명령 (단순 명령 참조), 목록 (목록 참조) 또는 복합 명령 (복합 명령 참조)으로 구성된 파이프 라인 (파이프 라인 참조)이 0이 아닌 상태를 반환하면 즉시 종료하십시오. 실패한 명령이 while 또는 until 키워드 바로 뒤에 오는 명령 목록의 일부인 경우 셸은 종료되지 않습니다 . if 문에서 테스트의 일부로, && 또는 ||로 실행되는 명령의 일부입니다. 마지막 && 또는 || 다음에 오는 명령, 파이프 라인의 모든 명령, 그러나 마지막 명령을 제외 하고 명령의 리턴 상태가 반전 된 경우를 제외하고는! . -e가 무시되는 동안 명령이 실패하여 서브 쉘이 아닌 복합 명령이 0이 아닌 상태를 리턴하면 쉘은 종료하지 않습니다. ERR에 대한 트랩이 설정되면, 쉘이 종료되기 전에 실행됩니다.

이러한 모든 사항을 고려하면 다음과 같은 경우가 있습니다.

set -e
! command1
command2

당신이하는 일은 command1set -e 플래그를 우회하는 것 set -e . 왜?

  • command1 이 제대로 실행되면 0 상태가 리턴됩니다. ! 그것을 무효로 할 것이지만, set -e 는 위에 설명 된 바와 같이!로 반전 된 리턴 상태에서 오기 때문에 exit를 트리거하지 않을 것이다.
  • command1 이 실패하면 0이 아닌 상태를 리턴합니다. ! 그것을 무효화 할 것이므로 라인은 0 상태로 돌아가고 스크립트는 정상적으로 계속됩니다.




sh