PIPESTATUS가 명령 대체 시 파이프에서 작동하지 않는 이유

PIPESTATUS가 명령 대체 시 파이프에서 작동하지 않는 이유

증명은 다음과 같습니다: Bash 4

Prompt> $(echo hello|sed 's/h/m/'|xargs -I{} ls {} 2>/dev/null|sed 's/ /_/')
Prompt> for i in ${PIPESTATUS[@]}; do echo $i;done
Output> 0

Prompt> echo hello|sed 's/h/m/'|xargs -I{} ls {} 2>/dev/null|sed 's/ /_/'
Prompt> for i in ${PIPESTATUS[@]}; do echo $i;done
Output> 0
Output> 0
Output> 123
Output> 0

명령 대체가 포그라운드 셸에서 실행되는 것으로 간주되지 않습니까? 이것은 내 추측이다.

답변1

PIPESTATUS명령 대체는 하위 쉘에서 실행되므로 상위 쉘의 변수를 변경하지 않습니다 . ~에서명령 실행 환경문서:

명령 대체, 괄호로 묶인 명령 및 비동기 명령은 쉘 환경과 중복되는 서브 쉘 환경에서 호출됩니다. 단, 쉘에 의해 잡힌 트랩은 쉘이 상위 쉘에서 상속받은 값으로 재설정됩니다. 기도. 파이프라인의 일부로 호출되는 내장 명령은 서브셸 환경에서도 실행됩니다. 서브쉘 환경에 대한 변경은 쉘의 실행 환경에 영향을 주지 않습니다.

PIPESTATUS서브셸에서 변수를 확인하면 예상되는 결과를 얻을 수 있습니다.

$ printf '%s\n' $(echo hello|sed 's/h/m/'|xargs -I{} ls {} 2>/dev/null|sed 's/ /_/';
for i in ${PIPESTATUS[@]}; do echo $i;done)
0
0
123
0

관련 정보