다음 스크립트를 사용하고 있습니다.
#!/bin/bash -Eu
trap 'echo Hi' ERR
exit_failure() {
echo "Hello, World!"
return 1
}
sub_failure() {
res=$(exit_failure)
}
sub_failure
결과는 다음과 같습니다.
Hi
Hi
그러나 sub_failure()
다음과 같이 변경하면 :
sub_failure() {
local res=$(exit_failure)
}
더 이상 출력이 나오지 ERR
않습니까? 신호가 숨겨져 있는 이유는 무엇입니까? ERR
지역 변수를 사용하려면 어떻게 캡처해야 합니까? 할 수 있다는 건 알지만 local res; res=$(exit_failure)
왜 둘을 분리해야 합니까?
답변1
이것은 실수가 아닙니다. 이것은 실제로 정의된 동작입니다.
당신이 그것을 사용할 때 bash -Eux
무슨 일이 일어나는지 볼 수 있습니다 . ( -Eu
당신의 shebang에서 + -x
)
+ trap 'echo Hi' ERR
+ sub_failure
++ exit_failure
++ echo 'Hello, World!'
++ return 1
+++ echo Hi
+ res='Hello, World!
Hi'
++ echo Hi
Hi
++ echo Hi
Hi
명령 대체를 수행할 때 스위치 trap
로 인해 -E
상속됩니다 . 따라서 함수 에 return 1
의해 트리거된 상속 트랩의 "Hi"는 . (실행 변형을 사용할 때도 마찬가지입니다 )exit_failure()
ret
local
또한 res=...
표현식은 1
(오류)를 반환하고 트랩( sub_failure()
함수 내부)을 트리거합니다.
res=...
함수의 return 및 결과 는 1
함수의 마지막 명령의 결과이므로 결과 도 (error) 이며 sub_failure()
메인 쉘에서 실행 1
후 트랩이 다시 트리거됩니다 . sub_failure
따라서 2개의 "Hi"가 표시됩니다. for res=....
및 for sub_failure
와 숨겨진 "Hi"가 에 저장됩니다 $res
.
local
이제 변형 에 대해 이야기해 보겠습니다 .
+ trap 'echo Hi' ERR
+ sub_failure
++ exit_failure
++ echo 'Hello, World!'
++ return 1
+++ echo Hi
+ local 'res=Hello, World!
Hi'
정의에 따르면, 함수 내에서 사용될 때 local
항상 반환됩니다 . 평가 결과 도 반환되기 때문에 숨겨진 "Hi"를 저장하면서 (성공) 로 평가하게 0
됩니다 . 따라서 이번에는 "숨겨진" 실패 하나와 성공 두 개를 얻게 됩니다.local res=...
0
$res
res=..
0
sub_failure
0
비록 이 스레드가 오래되었지만 도움이 되기를 바랍니다. ;)
local res=...
또한 우리가 분할 해야 하는 이유도 분명해야 합니다.
local res
res=....
첫 번째 변형의 동작을 복원합니다..? ;)