シェル変数は一般のプログラム言語における「スコープ」だけで捉えることはできず「その変数が存在するプロセスがどこになるか」を意識せねばなりません。
bash
1# (A) function
2function foo() {
3 g=$1
4 local l=$2
5}
6
7# (B) script in child process
8(
9 sleep 3s
10 str="hello"
11)&
上の(A)のようにfunctionを用いるとそのfunctionの実行は現在のbashプロセス内で行われるのでグローバル変数を更新することができます。ローカル変数も用いることができてその場合は関数の実行が終わると変数は消えます。
一方(B)のように()
で挟んでスクリプトを記述すると、子プロセスを生成しそこで実行されることになります。子プロセスは親プロセスの変数を引き継ぎますが子プロセスで変数を更新したりしても親プロセスにそれは反映されません。
子プロセスから親プロセスへ情報を伝える典型的な方法は標準出力を通じて親へ渡すことです。親は子供の標準出力を受け取りそれを変数へ代入することができます。
bash
1r=`echo foo`
2r=$(echo foo)
上記のようなコードを見たことがあると思います。どちらもechoは子プロセスで実行されますがバッククォートや$(...)
で囲むとその中で実行されるコマンドの標準出力結果を受け取り展開してくれるため子供プロセスの実行結果を親で利用することができるわけです。
あるいは複雑なことをするなら結果をファイルへ出力しておき後からそれを取り出すといったこともできるでしょう。
つまり子供プロセスで様々な変数的な情報を更新し、それを一つ一つ親へ反映させるような機構は「ない」と思います。
例えば次のように書けば意図しておられることに近いことができると思います。
bash
1(
2 (
3 sleep 3s
4 echo start
5 )&
6 wait
7 (
8 sleep 3s
9 echo "hello" >&4
10 )&
11 wait
12) 4> file1 &
13(
14 (
15 sleep 3s
16 echo end
17 )
18 wait
19)&
20wait
21
22echo "hello: $(cat file1)"
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2019/06/14 13:59 編集
2019/06/14 14:07
2019/06/14 19:05
2019/06/14 22:14 編集