$의 의미? 쉘 스크립트의 (달러 물음표)


답변:


212

마지막으로 실행 된 명령의 종료 상태입니다.

예를 들어이 명령은 true항상 상태를 반환 0하고 false항상 상태를 반환합니다 1.

true
echo $? # echoes 0
false
echo $? # echoes 1

매뉴얼에서 : (쉘을 호출 man bash하여 가능)

$?       가장 최근에 실행 된 포 그라운드 파이프 라인의 종료 상태로 확장됩니다.

일반적으로 종료 상태는 0성공 을 의미하고 0이 아닌 리턴 상태는 실패를 의미합니다. Wikipedia의 종료 상태 대해 자세히 알아보십시오 .

이 온라인 매뉴얼에서 볼 수 있듯이 이와 같은 다른 특수 변수가 있습니다 : https://www.gnu.org/s/bash/manual/bash.html#Special-Parameters


참고 $?두 개의 고유 한 매개 변수이며 $?bash (1) 맨 페이지에는 나타나지 않습니다.
Josh Habdas

19

$?마지막으로 실행 된 명령의 종료 값을 반환합니다. echo $?콘솔에서 해당 값을 인쇄합니다. 0은 성공적인 실행을 의미하지만 0이 아닌 값은 다양한 실패 이유에 매핑됩니다.

그러므로 스크립팅 할 때; 다음 구문을 사용하는 경향이 있습니다

if [ $? -eq 0 ]; then
 # do something
else
 # do something else
fi

비교는 같 0거나 같지 않습니다 0.

** 업데이트 의견에 따라 : 이상적으로, 위의 코드 블록을 비교에 사용해서는 안됩니다. @tripleee 의견 및 설명을 참조하십시오.


15
아니오, 이것은 반 패턴입니다. 겉 모습 cmd; if [ $? -eq 0 ]; then은로 리팩터링해야합니다 if cmd; then. 바로 그 목적if(쉘의 다른 흐름 제어 문)는 명령을 실행하고 종료 상태를 검사하는 것입니다.
tripleee

if cmd;cmd가 다른 스크립트를 참조 할 때 일부 조건이 읽기 어려울 수 있습니다.
Saurabh Ariyan 2016 년

1
이것은 지금 더 잘못되었습니다. [ 1 ]그리고 [ 0 ]둘 다 사실이다; [연산자가 없으면 인수가 비어 있지 않은 문자열인지 확인합니다.
tripleee 2016 년

2
하려고 해요 vendor/bin/drush status bootstrap | grep -q $(vendor/bin/drush php-eval 'if (function_exists("t")) echo t("Successful");') &> /dev/null;. if [ ... ]그것을 한 줄에 넣어야한다면 읽을 수 없을 것입니다. if [ $drupal_installed -eq 0 ]나중에 말할 수 있도록 해당 줄의 출력을 변수에 저장하려고합니다 .
thirdender

1
@thirdender 이에 대한 올바른 해결책은 복잡한 테스트를 쉘 함수로 캡슐화하는 것입니다.
tripleee

12

에코 $? - 가장 최근에 실행 된 명령 의 EXIT STATUS를 제공합니다 . 이 EXIT STATUS는 ZERO가 성공을 의미 하고 NON-ZERO 값이 실패를 나타내는 숫자 일 것입니다.

? -이것은 bash의 특수 매개 변수 / 변수 중 하나입니다.

$? -변수 "?"에 저장된 값을 제공합니다.

BASH의 유사한 특수 매개 변수는 1,2, *, #입니다 (일반적으로 echo 명령에서 $ 1, $ 2, $ *, $ # 등으로 표시).



5

최소 POSIX C 종료 상태 예

이해하려면 $?먼저 POSIX에서 정의한 프로세스 종료 상태 개념을 이해해야합니다 . 리눅스에서 :

  • 프로세스가 exit시스템 호출을 호출하면 커널 int은 프로세스가 종료 된 후에도 시스템 호출 ( )에 전달 된 값을 저장합니다 .

    출구 시스템 호출에 의해 호출 exit()ANSI C의 기능, 당신은 할 간접적 때 return부터 main.

  • 종종 fork+를 사용 하여 종료 하위 프로세스 (Bash)를 호출 한 프로세스 execwait시스템 호출 을 사용하여 하위의 종료 상태를 검색 할 수 있습니다.

Bash 코드를 고려하십시오.

$ false
$ echo $?
1

C "등가"는 다음과 같습니다.

false.c

#include <stdlib.h> /* exit */

int main(void) {
    exit(1);
}

bash.c

#include <unistd.h> /* execl */
#include <stdlib.h> /* fork */
#include <sys/wait.h> /* wait, WEXITSTATUS */
#include <stdio.h> /* printf */

int main(void) {
    if (fork() == 0) {
        /* Call false. */
        execl("./false", "./false", (char *)NULL);
    }
    int status;
    /* Wait for a child to finish. */
    wait(&status);
    /* Status encodes multiple fields,
     * we need WEXITSTATUS to get the exit status:
     * http://stackoverflow.com/questions/3659616/returning-exit-code-from-child
     **/
    printf("$? = %d\n", WEXITSTATUS(status));
}

컴파일하고 실행하십시오.

g++ -ggdb3 -O0 -std=c++11 -Wall -Wextra -pedantic -o bash bash.c
g++ -ggdb3 -O0 -std=c++11 -Wall -Wextra -pedantic -o false false.c
./bash

산출:

$? = 1

Bash에서 Enter 키를 누르면 위와 같이 fork + exec + wait가 발생하고 bash $?는 분기 된 프로세스의 종료 상태 로 설정 됩니다.

참고 :와 같은 내장 명령의 echo경우 프로세스를 생성 할 필요가 없으며 Bash $?는 외부 프로세스를 시뮬레이션하기 위해 0으로 설정 합니다.

표준 및 문서

POSIX 7 2.5.2 "특수 매개 변수" http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_05_02 :

? 가장 최근 파이프 라인의 10 진수 종료 상태로 확장됩니다 (파이프 라인 참조).

man bash "특수 매개 변수":

쉘은 여러 매개 변수를 특별히 처리합니다. 이 매개 변수는 참조 만 가능합니다. 그들에게 할당은 허용되지 않습니다. [...]

? 가장 최근에 실행 된 포 그라운드 파이프 라인의 종료 상태로 확장됩니다.

ANSI C와 POSIX는 다음을 권장합니다.

  • 0 프로그램이 성공적임을 의미

  • 다른 값 : 프로그램이 어떻게 든 실패했습니다.

    정확한 값은 실패 유형을 나타냅니다.

    ANSI C는 값의 의미를 정의하지 않으며 POSIX는 125보다 큰 값을 지정합니다. "POSIX"의 의미는 무엇입니까?

배시는 종료 상태를 사용합니다. if

Bash에서는 종종 다음과 같이 종료 상태를 $?암시 적으로 사용하여 if명령문 을 제어 합니다.

if true; then
  :
fi

어디 true0을 반환하는 프로그램은 ?

위의 내용은 다음과 같습니다.

true
result=$?
if [ $result = 0 ]; then
  :
fi

그리고 :

if [ 1 = 1 ]; then
  :
fi

[이상한 이름을 가진 프로그램 (그리고 Bash 내장 기능처럼 작동합니다)과 1 = 1 ]그 인수는 다음을 참조하십시오 : Bash의 단일 대괄호와 이중 대괄호의 차이점




2

마지막으로 실행 된 unix 명령의 결과를 출력합니다

0 implies true
1 implies false
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.