Bash
如何使子shell中的變數在父shell中可用
我已經編寫了一個快速而骯髒的腳本來為來自 Web 服務的一些報告計時:
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
命令包裝在一個子 shell 中,以便我可以重定向它的輸出,但這使得$response
父 shell 的值不可用。我該如何解決這個問題?
您不能將變數的值從子外殼帶到其父外殼,除非進行一些容易出錯的編組和繁瑣的通信。
幸運的是,這裡不需要子shell。重定向只需要命令分組,
{ … }
而不是子shell。{ time -p response=$(curl --write-out '%{http_code}' --silent -O "${BASE_URL}/${report_code}"); } 2> "${report_code}.time"
(不要忘記變數替換的雙引號。)
U&L 使用者:在否決我使用 C 風格與
main()
函式的答案之前,請訪問此連結:https ://unix.stackexchange.com/a/313561/85039在腳本中使用主要函式是一種常見做法,許多專業人士都在使用在該領域。正如 Gilles 所指出的,子 shell 不能使變數在其環境之外可用。但是讓我們從另一個角度來解決這個問題——如果你在函式中編寫腳本,就可以將變數聲明為
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 次迭代後看到的那樣,變數已被修改。