[shell] 셸에서 0이 참이지만 거짓이 1 인 이유는 무엇입니까?

false; echo $?

위의 출력 1은 내가 아는 다른 모든 프로그래밍 언어와 모순되는.

그 이유는 무엇입니까?



답변

관습이지만 생각할 때 특히 유용합니다. 일반적으로 프로그램이 성공하면 그만 알면됩니다. 그러나 실패하는 경우 실패에 대한 모든 종류의 정보 (발생 원인, 해결 방법 등)를 알아야 할 수 있습니다. 0은 ‘성공’을 의미하고 0이 아닌 평균 실패는 성공 여부를 매우 쉽게 확인할 수 있습니다. 을 클릭하고 원하는 경우 특정 오류를 조사하여 자세한 내용을 확인하십시오. 많은 API와 프레임 워크에는 비슷한 규칙이 있습니다. 성공한 함수는 0을 반환하고 실패한 함수는 특정 실패 사례를 설명하는 오류 코드를 반환합니다.


답변

Bash는 프로그래밍 (스크립팅) 언어이지만 셸이자 사용자 인터페이스이기도합니다. 0오류 인 경우 프로그램은 한 종류의 오류 만 표시 할 수 있습니다.

그러나 Bash에서 0이 아닌 값은 오류이며 1-255의 숫자를 사용하여 오류를 나타낼 수 있습니다. 이것은 우리가 다양한 종류의 오류를 가질 수 있음을 의미합니다. 1일반적인 오류, 126파일을 실행할 수 없음, 127‘명령을 찾을 수 없음’등을 의미합니다 . 다음 은 가장 일반적인 종료 코드 중 일부를 보여주는 특별한 의미 가있는 Bash 종료 코드 목록입니다 .

또한 많은 종류의 성공이 있습니다 (종료 상태는 0). 그러나 성공하면 다음 단계로 진행할 수 있습니다. 결과를 화면에 인쇄하거나 명령을 실행할 수 있습니다.


답변

여기에는 두 가지 관련 문제가 있습니다.

첫째, OP의 질문, 왜 0은 참이지만 거짓은 쉘에서 1입니까? 둘째, 응용 프로그램이 성공하면 0을 반환하고 실패하면 0이 아닌 이유는 무엇입니까?

OP의 질문에 답하려면 두 번째 질문을 이해해야합니다. 이 게시물에 대한 수많은 답변은 이것이 컨벤션이라고 설명했으며이 컨벤션이 제공하는 몇 가지 장점을 나열했습니다. 이러한 장점 중 일부는 아래에 요약되어 있습니다.

응용 프로그램이 성공하면 0을 반환하고 실패하면 0이 아닌 이유는 무엇입니까?

작업을 호출하는 코드는 작업의 종료 상태에 대해 두 가지를 알아야합니다. 작업이 성공적으로 종료 되었습니까? [* 1] 그리고 작업이 성공적으로 종료되지 않은 경우 작업이 성공적으로 종료 된 이유는 무엇입니까? 모든 값을 사용하여 성공을 나타낼 수 있습니다. 그러나 0은 플랫폼간에 이식 가능하기 때문에 다른 숫자보다 편리합니다. 2011 년 8 월 16 일 이 질문 에 대한 xibo의 답변 요약 :

0은 인코딩에 독립적입니다.

32 비트 정수 단어에 one (1)을 저장하려는 경우 첫 번째 질문은 “빅 엔디안 단어 또는 리틀 엔디안 단어?”와 “바이트가 리틀 엔디안 단어를 구성하는 길이?”입니다. “, 0은 항상 동일하게 보입니다.

또한 어떤 사람들은 errno를 어떤 시점에서 char 또는 short로 캐스팅하거나 심지어 float로 캐스팅 할 것으로 예상해야합니다. (int) ((char) ENOLCK)는 char 길이가 8 비트 이상 (UNIX에서 7 비트 ASCII char 시스템을 지원함)이 아닐 때 ENOLCK가 아닌 반면 (int) ((char) 0)은 char의 건축 세부 사항.

0이 성공에 대한 반환 값이라고 결정되면 0이 아닌 값을 실패에 사용하는 것이 좋습니다. 이를 통해 많은 종료 코드 가 작업이 실패한 이유에 대한 질문에 답할 수 있습니다 .

셸에서 0이 참이지만 거짓이 1 인 이유는 무엇입니까?

쉘의 기본적인 사용법 중 하나는 스크립팅을 통해 프로세스를 자동화하는 것입니다. 일반적으로 이것은 작업을 호출 한 다음 작업의 종료 상태에 따라 조건부로 다른 작업을 수행하는 것을 의미합니다. Philippe A. 는이 게시물에 대한 그의 답변에서

일반적으로 bash 및 유닉스 셸에서 반환 값은 부울이 아닙니다. 정수 종료 코드입니다.

그런 다음 이러한 작업의 종료 상태를 부울 값으로 해석해야합니다. 성공 ( 0) 종료 상태를 true 로 매핑하고 0이 아닌 / 실패 종료 상태를 false 로 매핑하는 것이 좋습니다 . 이렇게하면 연결된 쉘 명령을 조건부로 실행할 수 있습니다.

여기에 예가 mkdir deleteme && cd $_ && pwd있습니다. 쉘이 0을 참으로 해석하기 때문에이 명령은 예상대로 편리하게 작동합니다. 쉘이 0을 거짓으로 해석한다면 각 작업에 대해 해석 된 종료 상태를 반전해야합니다.

요컨대, 응용 프로그램이 성공적인 종료 상태에 대해 0을 반환한다는 규칙을 고려할 때 쉘이 0을 거짓으로 해석하는 것은 의미가 없습니다.


[* 1] : 예, 여러 번 작업에서 단순한 성공 메시지 이상을 반환해야하지만 이는이 스레드의 범위를 벗어납니다.

고급 Bash 스크립팅 가이드의 부록 E 를 참조하십시오.


답변

제가 이해해야 할 중요한 점은 이것입니다. 일반적으로 bash 및 유닉스 셸에서 반환 값은 부울이 아닙니다. 정수 종료 코드입니다. 따라서 0은 성공을 의미하고 다른 값은 오류를 의미한다는 규칙에 따라 평가해야합니다.

test, [ ]또는 [[ ]]운영자, 배쉬 조건은 종료 코드 0 (의 / 빈 / 진정한 결과)의 경우에는 사실로 평가합니다. 그렇지 않으면 거짓으로 평가됩니다.

문자열은 종료 코드와 다르게 평가됩니다.

if [ 0 ] ; then echo not null ; fi
if [ $(echo 0) ] ; then echo not null ; fi

if [ -z "" ] ; then echo null ; fi

(( ))연산기 참과 거짓으로 1과 0을 해석한다. 그러나이 연산자는 test, [ ]또는 의 완전한 대체물로 사용할 수 없습니다 [[ ]]. 다음은 산술 연산자가 유용한 경우를 보여주는 예입니다.

for (( counter = 0 ; counter < 10 ; counter ++ )) ; do
  if (( counter % 2 )) ; then echo "odd number $counter" ; fi
done


답변

0 종료 코드는 성공을 의미하는 규칙입니다. EXIT_SUCCESS 는 거의 모든 최신 시스템에서 0이됩니다.

편집하다:

“테스트 0과 테스트 1이 모두 0 (성공)을 반환하는 이유는 무엇입니까?”

그것은 완전히 다른 질문입니다. 대답은 테스트에 단일 인수를 전달하면 해당 인수가 널 문자열 ( “”)이 아닌 한 항상 성공한다는 것입니다. Open Group 문서를 참조하십시오 .


답변

일반적으로 프로그램은 성공하면 0을, 실패하면 0이 아닌 값을 반환합니다. false편리한 0이 아닌 값이기 때문에 1을 반환하지만 일반적으로 0이 아닌 값은 일종의 실패를 의미하며 많은 프로그램은 다른 실패 모드를 나타 내기 위해 다른 0이 아닌 값을 반환합니다.


답변

AFAIK 이것은 성공하면 0을 반환해야하는 C 규칙에서 비롯됩니다. 보다:

man close

대부분의 C (POSIX) API는 다음과 같이 빌드됩니다.
http://en.wikipedia.org/wiki/C_POSIX_library