다음 코드를 고려하십시오
outer-scope.sh
#!/bin/bash
set -e
source inner-scope.sh
echo $(inner)
echo "I thought I would've died :("
inner-scope.sh
#!/bin/bash
function inner() { echo "winner"; return 1; }
에 outer-scope.sh
대한 호출이 inner()
실패하면 종료 하려고 합니다. $()
서브 쉘을 호출하기 때문에 이런 일이 발생하지 않습니다.
함수가 0이 아닌 종료 코드로 종료 될 수 있다는 사실을 유지하면서 함수의 출력을 얻으려면 어떻게해야합니까?
답변
$()
종료 상태를 유지합니다. 할당과 같이 자체 상태가없는 명령문에 사용하면됩니다.
출력 = $ (내부)
이 후에 $?
는 종료 상태가 포함되며 inner
모든 종류의 검사를 사용할 수 있습니다.
output=$(inner) || exit $?
echo $output
또는:
if ! output=$(inner); then
exit $?
fi
echo $output
또는:
if output=$(inner); then
echo $output
else
exit $?
fi
(참고 : exit
인자가없는 베어 exit $?
는 마지막 명령의 종료 상태로 종료됩니다. 두 번째 형식은 명확성을 위해서만 사용했습니다.)
또한 레코드의 경우 : source
이 경우 완전히 관련이 없습니다. 당신은 정의 할 수 있습니다 inner()
에서 outer-scope.sh
같은 결과를 파일.
답변
BashFAQ / 002 참조 :
둘 다 원하는 경우 (출력 및 종료 상태) :
output=$(command)
status=$?
특별한 경우
함수 로컬 변수가있는 까다로운 경우에 대해 다음 코드를 비교하십시오.
f() { local v=$(echo data; false); echo output:$v, status:$?; }
g() { local v; v=$(echo data; false); echo output:$v, status:$?; }
우리는 얻을 것이다 :
$ f # fooled by 'local' with inline initialization
output:data, status:0
$ g # a good one
output:data, status:1
왜?
서브 쉘의 출력이 local
변수 를 초기화하는 데 사용될 때, 종료 상태는 더 이상 서브 쉘이 아니라 명령 일 가능성이 높습니다 .local
0
답변
#!/bin/bash
set -e
source inner-scope.sh
foo=$(inner)
echo $foo
echo "I thought I would've died :("
을 추가 echo
하면 서브 쉘이 독립형이 아니고 (별도로 점검되지 않음) 중단되지 않습니다. 할당은이 문제를 우회합니다.
이 작업을 수행하고 출력을 파일로 리디렉션하여 나중에 처리 할 수도 있습니다.
tmpfile=$( mktemp )
inner > $tmpfile
cat $tmpfile
rm $tmpfile