私は、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
コマンドをサブシェルでラップする必要がありますが、これにより$response
の値が親シェルで使用できなくなります。この問題を回避するにはどうすればよいですか?
変数の値をサブシェルからその親にもたらすことはできません。エラーが発生しやすいマーシャリングと面倒な通信を行わなければ、それができません。
幸い、ここにはサブシェルは必要ありません。リダイレクトに必要なのは コマンドのグループ化 と{ … }
、サブシェルではありません。
{ time -p response=$(curl --write-out '%{http_code}' --silent -O "${BASE_URL}/${report_code}"); } 2> "${report_code}.time"
(忘れないでください 変数置換を囲む二重引用符 。)
仲間の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回繰り返した後にわかるように、変数は変更されています。