웹 서비스에서 일부 보고서의 시간을 측정하기 위해 빠르고 간단한 스크립트를 작성했습니다.
BASE_URL='http://example.com/json/webservice/'
FIRST=1
FINAL=10000
for report_code in $(seq 1 $FINAL); do
(time -p response=$(curl --write-out %{http_code} --silent -O ${BASE_URL}/${report_code}) ) 2> ${report_code}.time
echo $response # <------- this is out of scope! How do I fix that?
if [[ $response = '404' ]]; then
echo "Deleting report # ${report_code}!"
rm ${report_code}
else
echo "${report_code} seems to be good!"
fi
done
time
출력을 리디렉션할 수 있도록 하위 쉘에서 명령을 래핑 해야 하지만 이로 인해 $response
상위 쉘에서 값을 사용할 수 없게 됩니다. 이 문제를 어떻게 해결할 수 있나요?
답변1
오류가 발생하기 쉬운 마샬링 및 번거로운 통신 없이는 하위 쉘에서 상위 쉘로 변수 값을 전달할 방법이 없습니다.
다행히 여기에는 하위 쉘이 필요하지 않습니다. 리디렉션에는 다음 사항만 필요합니다.명령 그룹화을 사용하면 { … }
서브쉘이 아닙니다.
{ time -p response=$(curl --write-out '%{http_code}' --silent -O "${BASE_URL}/${report_code}"); } 2> "${report_code}.time"
(잊지 마요변수 대체는 큰따옴표로 묶입니다..)
답변2
동료 U&L 사용자: main()
C 스타일 함수 사용에 대한 내 답변을 반대하기 전에 다음 링크를 방문하세요.https://unix.stackexchange.com/a/313561/85039스크립트에서 주요 기능을 사용하는 것은 해당 분야의 많은 전문가들이 사용하는 일반적인 방법입니다.
Gilles가 지적했듯이 서브쉘은 환경 외부에서 변수를 사용할 수 없도록 만들 수 없습니다. 하지만 이를 다른 각도에서 접근해 보겠습니다. 함수에 스크립트를 작성하면 변수를 선언 local
하고 편집할 수 있습니다.
Bash 4.3 매뉴얼에서 local
설명:
...local이 함수 내에서 사용되면 변수 이름이 해당 함수와 해당 하위 함수에만 표시됩니다.
예:
#!/bin/bash
outter()
{
for i in $(seq 1 3)
do
var=$i
done
}
main()
{
local var=0
outter
echo $var
}
main "$@"
$ ./testscript.sh
3
보시다시피 루프 함수가 3번 반복된 후 변수가 수정됩니다.
답변3
a에서 변수를 리디렉션 test.txt
하고 상위 셸에서 가져올 수 있습니다.
testfn()
{
echo "test" > test.txt # redirect your variable in a test.txt
}
testfn & # execute your function in the subshell
testresult=$(cat test.txt) # get your variable in the parent shell
printf '%s\n' "$testresult"
답변4
bash 4.3부터 할 수 있습니다이름 참조 변수
#!/usr/bin/env bash
# outvar is a nameref variable that allows us to set the value of a variable
# outside our scope
addfoo() {
local x="$1"
local -n outvar=$2
x="foo$x"
outvar="$x"
}
declare b=“loll”
addfoo "bar" b
echo "$b”
이는 foobar
함수가 범위 밖에서 도 변수를 addfoo
수정할 때 출력됩니다.b
b
Nameref는 서브쉘을 사용하지 않고 함수에서 값을 추출하는 데 유용합니다 $(addfoo)
.