할당은 명령 대체가있는 경우를 제외하고 종료 상태의 명령과 비슷합니까?


10

POSIX 쉘에서 다음 예제 및 해당 출력을 참조하십시오.

  1. false;echo $?또는 false || echo 1:1
  2. false;foo="bar";echo $?또는 foo="bar" && echo 0:0
  3. foo=$(false);echo $?또는 foo=$(false) || echo 1:1
  4. foo=$(true);echo $?또는 foo=$(true) && echo 0:0

/programming/6834487/what-is-the-variable-in-shell-scripting 에서 가장 투표가 많은 답변에서 언급했듯이 :

$? 마지막으로 실행 된 명령의 반환 값을 찾는 데 사용됩니다.

이 경우에는 약간 오해의 소지가 있으므로 해당 스레드의 게시물에 인용 된 POSIX 정의를 가져 오십시오.

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

따라서 할당 자체가 종료 값이 0 인 명령 (또는 파이프 라인 부분)으로 계산되지만 할당 오른쪽 앞에 적용되는 것처럼 보입니다 (예 : 여기에서 명령 대체 호출).

이 행동이 실제적인 관점에서 어떻게 의미가 있는지 알지만 과제 자체가 그 순서대로 계산되는 것은 다소 특이한 것 같습니다. 왜 나에게 이상한지 더 명확하게하기 위해 과제가 함수라고 가정 해 봅시다.

ASSIGNMENT( VARIABLE, VALUE )

다음 foo="bar"

ASSIGNMENT( "foo", "bar" )

그리고 foo=$(false)같은 것

ASSIGNMENT( "foo", EXECUTE( "false" ) )

즉, 먼저EXECUTE 실행 되고 나중에 만 실행되지만 여전히 여기서 중요한 상태입니다. ASSIGNMENTEXECUTE

평가가 정확합니까, 아니면 오해 / 누락이 있습니까? 이러한 행동을 "이상한"것으로 보는 올바른 이유가 있습니까?


1
죄송하지만 이상한 점이 무엇인지 확실하지 않습니다.
Kusalananda

1
@Kusalananda는 어쩌면 그것은 자신을 물어 저와 함께 시작하는 것이 당신에게 도움이 : "왜 않습니다 false;foo="bar";echo $?실행 된 마지막 실제 명령했다 때 항상 0을 반환 false?" 기본적으로 과제는 종료 코드와 관련하여 특별하게 작동합니다. 과제의 오른쪽 부분으로 실행 된 것이 아니기 때문에 종료 코드는 항상 0입니다.
phk

답변:


10

할당 종료 상태가 이상 합니다. 할당이 실패하는 가장 확실한 방법은 대상 변수가로 표시되어있는 것 readonly입니다.

$ err(){ echo error ; return ${1:-1} ; }
$ PS1='$? $ '
0 $ err 42
error
42 $ A=$(err 12)
12 $ if A=$(err 9) ; then echo wrong ; else E=$? ; echo "E=$E ?=$?" ; fi
E=9 ?=0
0 $ readonly A
0 $ if A=$(err 10) ; then echo wrong ; else E=$? ; echo "E=$E ?=$?" ; fi
A: is read only
1 $

if 문의 true 또는 false 경로를 모두 취하지 않고 할당 실패로 인해 전체 명령문의 실행이 중지되었습니다. POSIX 모드의 bash 및 할당이 실패하면 ksh93 및 zsh가 모두 스크립트를 중단합니다.

이것에 대한 POSIX 표준 을 인용하려면 :

명령 이름이 없지만 명령 대체가 포함 된 명령은 쉘이 수행 한 마지막 명령 대체의 종료 상태를 갖습니다.

이것은 정확히 관련된 쉘 문법의 일부입니다

 foo=$(err 42)

이것은 simple_command(simple_command → cmd_prefix → ASSIGNMENT_WORD)에서 나옵니다. 따라서 지정이 성공하면 명령 대체가 포함되지 않는 한 종료 상태는 0이며,이 경우 종료 상태는 마지막 상태입니다. 할당이 실패하면 종료 상태는 0이 아니지만이를 포착하지 못할 수 있습니다.


1
: 여기에 새로운 POSIX 표준은 인용 된 다른 스레드에서 답변입니다, 당신의 대답에 추가하려면, 결론은 기본적으로 동일 unix.stackexchange.com/a/270831/117599
phk

4

당신은 말합니다

… 할당 자체가 명령으로 계산되는 것처럼 보이지만 종료 값이 0이지만 할당 오른쪽 앞에 적용됩니다 (예 : 명령 대체 호출…).

그것은 그것을 보는 끔찍한 방법이 아닙니다. 그러나 약간 단순화 된 것입니다. 의 전체 반품 상태

A = $ ( cmd 1 ) B = $ ( cmd 2 ) C = $ ( cmd 3 ) D = $ ( cmd 4 ) E = mc 2
의 종료 상태입니다 . 애프터 발생 할당 할당은 0으로 전반 종료 상태를 설정하지 않습니다.cmd4E=D=

또한, icarus가 지적한 것처럼 변수는 읽기 전용으로 설정할 수 있습니다. 이카루스의 예에서 다음과 같은 변형을 고려하십시오.

$ err() { echo "stdout $*"; echo "stderr $*" >&2; return ${1:-1}; }
$ readonly A
$ Z=$(err 41 zebra) A=$(err 42 antelope) B=$(err 43 badger)
stderr 41 zebra
stderr 42 antelope
bash: A: readonly variable
$ echo $?
1
$ printf "%s = %s\n" Z "$Z" A "$A" B "$B"
Z = stdout 41 zebra
A =
B =
$

비록 A읽기 전용, 배쉬의 오른쪽에있는 명령 치환을 실행 A=- 그리고 다음 있기 때문에 명령을 중단 A읽기 전용입니다. 이는 과제의 종료 값이 과제의 오른쪽보다 먼저 적용된다는 해석과 모순됩니다.

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