bash 의 종료 상태 메커니즘
프로그램 이 끝 날 때 부모 프로 세 스에 자신의 종료 상태
exit status
를 보고 합 니 다. int
형식의 변 수 를 전달 하여 라 이브 러 리 함수 exit
나 시스템 호출 _exit
을 통 해 현재 프로그램의 종료 상 태 를 설정 할 수 있 습 니 다. Linux
에서 WEXITSTATUS
를 통 해 돌아 오 는 종료 상태의 값 영역 은 [0, 255]
입 니 다.사이 의 정수 입 니 다. 전달 하 는 값 이 이 범위 안에 있 지 않 으 면 커 널 은 자동 으로 u_int8_t
로 강 전 됩 니 다. waitpid
라 이브 러 리 함 수 를 통 해 하위 프로 세 스 의 종료 상 태 를 얻 을 수 있 습 니 다. 그 값 은 매개 변수 wstatus
의 낮은 8
비트 에 저 장 됩 니 다.// wait.h
# define WEXITSTATUS(status) __WEXITSTATUS (status)
// waitstatus.h
/* If WIFEXITED(STATUS), the low-order 8 bits of the status. */
#define __WEXITSTATUS(status) (((status) & 0xff00) >> 8)
다음 예 는 하위 프로 세 스 의 종료 상 태 를 어떻게 사용 하 는 지 보 여 줍 니 다
waitpid
.#include
#include
#include
#include
#include
#define PARENT_EXIT 10086
#define CHILD_EXIT -10
int main()
{
pid_t pid = fork();
if (pid > 0)
{
int wstatus;
// , WUNTRACED
pid_t child_pid = waitpid(pid, &wstatus, WUNTRACED);
if (WIFEXITED(wstatus))
printf("Child exit status: %d
", WEXITSTATUS(wstatus));
else
perror("Bad wait status
");
//
exit(PARENT_EXIT);
}
else if (pid == 0)
{
// , WUNTRACED
exit(CHILD_EXIT);
}
else
{
// fork
perror("fork
");
exit(EXIT_FAILURE);
}
}
이전 예 를 컴 파일 하고 실행 하면 강 전 된 상태 코드 를 얻 을 수 있 습 니 다. 우 리 는
WIFEXITED
을 사용 하여 기다 리 는 하위 프로 세 스 가 성공 적 으로 실행 되 었 는 지 판단 한 다음 에 성공 적 인 하위 프로 세 스 WEXITSTATUS
를 실행 하여 종료 상 태 를 가 져 옵 니 다. 프로그램 에 있어 서 최종 종료 상 태 는 메 인 프로 세 스 의 종료 상태 입 니 다.> gcc ecitcode.c;./a.out;echo "Parent exit status: $?"
Child exit status: 246 # -10 uint8
Parent exit status: 102 # 10086 uint8
POSIX
기준 에서 탈퇴 상태 0
는 이 프로그램의 정상 적 인 탈퇴 를 대표 하고 1
는 오류 가 발생 했 으 며 다른 숫자 는 프로그램 이 자체 적 으로 규정 하기 때문에 glibc
의 stdlib.h
에서 다음 과 같은 매크로 만 정의 했다.#define EXIT_FAILURE 1 /* Failing exit status. */
#define EXIT_SUCCESS 0 /* Successful exit status. */
프로그램 자 체 는 일반적으로 문서 에서 모든 종료 상태 대표 의 종료 원인
termination
을 미리 약정 합 니 다. 예 를 들 어 ls
도움말 문서 에서:> ls --help
... ...
Exit status: #
0 if OK, #
1 if minor problems # , :
2 if serious trouble # , :
... ...
명령 의 종료 상태
bash
에 실 행 된 명령 의 종료 상 태 를 기록 합 니 다. $?
을 통 해 최근 실 행 된 명령 의 종료 상 태 를 얻 을 수 있 습 니 다. bash
자신의 종료 상 태 는 실 행 된 마지막 명령 의 종료 상태 이 며, 명시 적 지정 exit $?
과 같 습 니 다. 명령 을 실행 하지 않 고 종료 하면 bash
의 종료 상 태 는 0
입 니 다.bash
에서 0
로 true
표시 하고 비 0 으로 false
표시 하 는 것 에 주의해 야 한다.# exit
> bash
> exit 98
exit
> echo $?
98
# 0
> bash
exit # Ctrl + D
> echo $?
0
#
> bash
> ecasd
ecasd: command not found
exit # Ctrl + D
> echo $?
127
bash
에서 서로 다른 종류의 명령 의 탈퇴 상태 에 대해 다음 과 같은 규정 을 한다.내 장 된 명령: 내 장 된 명령 이 실 행 될 때 추가 하위 프로 세 스 를 시작 할 필요 가 없 기 때문에 반환 값 으로 종료 상 태 를 모 의 해 야 합 니 다. 모든 함수 가 자신의 종료 상 태 를 정의 합 니 다. 예 를 들 어 내 장 된 명령
source
은 스 크 립 트 파일 의 마지막 명령 의 반환 상 태 를 명령 의 반환 상태 로 합 니 다. bash
의 모든 내 장 된 명령 은 종료 상태 2
를 사용 합 니 다.예 를 들 어 옵션 오류, 인자 가 부족 합 니 다.> cd -+- #
bash: cd: -+: invalid option
cd: usage: cd [-L|[-P [-e]] [-@]] [dir]
> echo $?
2
외부 명령: 외부 명령 의 종료 상 태 는
waitpid
받 은 하위 프로 세 스 의 종료 상 태 를 사용 하 는 것 입 니 다. 하위 프로 세 스 가 실행 과정 에서 번호 N
의 신호 로 종료 되면 종료 상 태 는 128+N
입 니 다.Shell 함수: 정의
shell
함수 시 함수 명 은 이전에 정 의 된 읽 기 전용 함수 명 과 같 으 면 종료 상태 1
이 고 문법 오류 가 발생 하면 종료 상태 2
입 니 다. shell
함 수 를 실행 할 때 함수 에서 마지막 으로 실 행 된 명령 의 종료 상 태 는 전체 함수 의 종료 상태 입 니 다.#
> func () { echo; }
> readonly -f func
> func; echo $?
0
> func () { echo poi; }
bash: func: readonly function
> echo $?
1
#
> fune () {aa}
bash: syntax error near unexpected token '{aa}'
> echo $?
2
#
> funr () { echo; return 6; }
> funr; echo $?
# echo
6 # return 6
표현 식:
((...))
또는 let
수식 표현 식 의 종료 상 태 는 표현 식 의 값 에 달 려 있 습 니 다. 표현 식 의 값 이 0
이면 종료 상 태 는 1
입 니 다.표현 식 의 값 이 0 이 아니라면 종료 상 태 는 0
입 니 다.> let 0+0; echo $?
1 #
> ((7-5)); echo $?
0 #
명령 목록:
;
, &
, &&
, ||
로 연결 명령 을 명령 목록 이 라 고 합 니 다. 그 중에서 &&
와 ||
로 연 결 된 명령 은 왼쪽 연결 left associativity
모드 로 목록 의 명령 을 수행 합 니 다. 전체 명령 목록 의 종료 상 태 는 마지막 명령 의 종료 상태 입 니 다. 그 밖 에 $( LISTS )
및 절차 제어 구 조 는 다음 과 같 습 니 다.for
, while
등의 반환 상태 도 구조 중의 명령 목록 의 종료 상태 입 니 다.# : ping baidu.com `baidu.com is up` , `baidu.com is down` 。
> ping -c1 baidu.com &> /dev/null && echo 'baidu.com is up' || echo 'baidu.com is down'
baidu.com is down
> echo $?
0 # ping ,
왼쪽 관련 모델 은 각종 언어의 논리 연산 자 최적화 에 광범 위 하 게 응용 된다. 논리 와 연산 자 에 대해
&&
로eq1 && eq2
예 를 들 면 양쪽 만True
돌아 갑 니 다.그래서
True
는eq1
시,False
실행 되 지 않 습 니 다. 논리 나 연산 자 에 대해 서 는...eq2
로||
예 를 들 면 양쪽 에 하나만 있 으 면eq1 || eq2
돌아 갑 니 다.그래서
True
는True
시,eq1
집행 하지 않 습 니 다.스 크 립 트: 사용
True
또는 eq2
스 크 립 트 파일 을 실행 하 는 것 은 현재 .
에서 코드 블록 을 실행 하 는 것 과 같 습 니 다. 스 크 립 트 에서 마지막 으로 실 행 된 명령 의 종료 상 태 는 스 크 립 트 의 종료 상태 입 니 다. 사용 source
또는 bash
방식 으로 스 크 립 트 파일 을 실행 하 는 것 은 외부 명령 을 실행 하 는 것 과 같 습 니 다. 스 크 립 트 의 종료 상 태 는 외부 명령 ./
입 니 다.의 종료 상태 입 니 다. 스 크 립 트 에서 마지막 으로 실 행 된 명령 이 bash
이면 bash
또는 exit
이 스 크 립 트 파일 을 실행 하면 실행 이 끝 난 후에 현재 .
를 종료 합 니 다.백 스테이지 작업 과 협업 프로 세 스: 옵션 이 없 는
source
명령 을 사용 하면 마지막 으로 실 행 된 백 스테이지 작업 의 종료 상 태 를 얻 을 수 있 습 니 다. bash
를 사용 하면 지정 한 백 스테이지 작업 의 종료 상 태 를 얻 을 수 있 습 니 다. 작업 이 존재 하지 않 으 면 종료 상 태 는 wait
입 니 다. 사용 wait -n
은 127
에 있 습 니 다.에서 실 행 된 명령 의 종료 상 태 는 백 스테이지 작업 과 마찬가지 로 coproc
가 져 올 수 있 습 니 다. sub shell
자신의 종료 상 태 는 항상 wait
입 니 다.> { sleep 10; aad; } &
[1] 558
> wait -n 1
[1]+ Exit 127 { sleep 10; aad; }
> coproc { sleep 10; aad; }
[1] 558
> echo $?
0 # coproc
> jobs
[1]+ Exit 127 coproc COPROC { sleep 10; aad; }
파이프 명령: 기본적으로 파이프 의 종료 상 태 는 파이프 의 마지막 명령 의 종료 상태 에 달 려 있 습 니 다.
coproc
설정 되 어 있 으 면 파이프 의 모든 명령 의 종료 상태 가 0
일 때 만 전체 파이프 의 종료 상태 가 set -o pipefail
이 고 그렇지 않 으 면 마지막 0 이 아 닌 종료 상태 입 니 다. 파이프 앞 에 추가 0
기 호 는 전체 파이프 의 종료 상태 에 대해 반대 할 수 있 습 니 다. 0
중의 특수 변수 !
는 최근 에 실 행 된 프론트 파이프 의 종료 상 태 를 배열 로 저장 할 수 있 습 니 다. 주의해 야 할 것 은 하나의 명령 도 기록 되 는 것 입 니 다. 즉, bash
과 $PIPESTATUS
은 등가 입 니 다.#
> ps | xxp 2>/dev/null | cat; echo $?
0
> set -o pipefail
> ps | xxp 2>/dev/null | cat; echo $?
127 # pipefail
#
> easd 2>/dev/null | ls /nou 2>/dev/null | more 2>/dev/null
> echo ${PIPESTATUS[@]}
127 2 0
#
> ping asbasdasd 2>/dev/null; echo ${PIPESTATUS[0]}
2
> ping asbasdasd 2>/dev/null; echo $?
2
참고 자료
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
성공할 때까지 명령 실행최근에 유용한 간단한 BASH 패턴: Run command every time it fails until it doesn't fail. 예시 작은 배치로 수십만 개의 레코드를 내보내야 하는 장기 실행 작업이 있었습니...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.