グローバル変数foo = "some value"とバックグラウンドプロセスback_funcがあり、バックグラウンドプロセスで$ fooにアクセスし、その値を変更します。これはメインプロセスで確認できます。次のようなものです。
#!/bin/bash
foo=0
function back_func {
foo=$(($foo+1))
echo "back $foo"
}
(back_func) &
echo "global $foo"
上記のスクリプトの結果は次のとおりです。
global 0
back 1
グローバルとバックの両方が「1」の結果を取得するにはどうすればよいですか?つまり、バックグラウンドプロセスの変更をメインプロセスに戻すことができます。
_bash_ipc_demo
_で遊んで、補完とグラフジェネレーターを追加します。
通信できる2つの独立したプロセスが必要な場合は、両方のプロセスが到達できる場所にrendez-vousを配置する必要があります。
これは、単純なファイル、FIFOパイプ、UNIXソケット、TCPソケット、またはその他(Rexxポート)の場合があります。
Bashにはrexxポートに相当するものがないため、(私のLinuxで)動作するランデブーファイルを使用したサンプルが少しあります。
ディスクの負荷を減らすために、共有メモリ _/dev/shm
_を使用しています。
_$ back_func() {
while :;do
echo $(($(</dev/shm/foo)+1)) >/dev/shm/foo;
sleep .3;
done;
}
_
遊ぼう
_$ echo 1 >/dev/shm/foo
$ back_func &
$ echo $(</dev/shm/foo)
4
$ echo $(</dev/shm/foo)
21
_
今やめるより:
_$ fg
back_func
^C
_
または
_$ kill $!
$
[1]+ Terminated back_func
_
多くの変数を持っているために、素晴らしい方法である可能性があります:
_$ back_func() {
declare -A MYGLOBAL
local vars
while :; do
((MYGLOBAL["counter"]++))
IFS=\ / read -a vars <<< "$(</proc/uptime) $(</proc/loadavg)"
MYGLOBAL["uptime"]=$vars
MYGLOBAL["idle"]=${vars[1]}
MYGLOBAL["l01m"]=${vars[2]}
MYGLOBAL["l05m"]=${vars[3]}
MYGLOBAL["l15m"]=${vars[4]}
MYGLOBAL["active"]=${vars[5]}
MYGLOBAL["procs"]=${vars[6]}
MYGLOBAL["lpid"]=${vars[7]}
MYGLOBAL["Rand"]=$RANDOM
MYGLOBAL["crt"]=$SECONDS
declare -p MYGLOBAL > /dev/shm/foo
sleep 1
done
}
_
次に
_$ back_func &
[1] 27429
$ . /dev/shm/foo
$ echo ${MYGLOBAL['counter']}
5
$ echo ${MYGLOBAL['lpid']}
27432
_
そしてそこから、なぜそうではありません:
_$ dumpMyGlobal() {
. /dev/shm/foo
printf "%8s " ${!MYGLOBAL[@]}
echo
printf "%8s " ${MYGLOBAL[@]}
echo
}
$ dumpMyGlobal
l15m uptime crt procs lpid active Rand idle l05m
counter l01m
0.42 13815568.06 95 554 649 1 31135 21437004.95
0.38 73 0.50
$ dumpMyGlobal
l15m uptime crt procs lpid active Rand idle l05m
counter l01m
0.41 13815593.29 120 553 727 2 3849 21437046.41
0.35 98 0.33
_
または
_$ dumpMyGlobal() {
. /dev/shm/foo
sort <(
paste <(
printf "%-12s\n" ${!MYGLOBAL[@]}
) <(printf "%s\n" ${MYGLOBAL[@]})
)
}
$ dumpMyGlobal
active 1
counter 297
crt 337
idle 21435798.86
l01m 0.40
l05m 0.44
l15m 0.45
lpid 30418
procs 553
Rand 7328
uptime 13814820.80
_
そして最後にgetMyGlobalVar
関数
_$ declare -A MYGLOBALLOCK # snapshot variable
$ getMyGlobalVar () {
local i sync=false
[ "$1" == "--sync" ] && shift && sync=true
if [ -z "${MYGLOBALLOCK[*]}" ] || $sync; then
. /dev/shm/foo
for i in ${!MYGLOBAL[@]}
do
MYGLOBALLOCK[$i]=${MYGLOBAL[$i]}
done
fi
echo ${MYGLOBALLOCK[$1]}
}
_
同じsnapshotから各フィールドを確認できるようにするには、再読み取りに_--sync
_フラグが必要になりますrendez-vous。
_$ getMyGlobalVar --sync idle
362084.12
$ getMyGlobalVar idle
362084.12
$ getMyGlobalVar Rand
1533
$ getMyGlobalVar Rand
1533
$ getMyGlobalVar --sync Rand
43256
$ getMyGlobalVar idle
362127.63
_
完全なサンプルがあります: bash_ipc_demo または bash_ipc_demo.shz
次の方法で使用できます。
_wget http://f-hauri.ch/vrac/bash_ipc_demo
source bash_ipc_demo
back_func help
Usage: back_func [-q] [start [-g N]|stop|restart|status|get|dump|help]
-q Quiet
-g N Start daemon, setting uptime_useGraph to N values
back_func status
Background loop function is not running.
back_func start -g 3600
back_func status
Background loop function (19939) is running.
_
そこから、別の端末で_source bash_ipc_demo
_を実行すると、それらにリストを追加できます。
最初のターミナルを閉じることもできます。
_back_func dump
backFunc_count 13
backFunc_now 2016-04-06 17:03:19
backFunc_pid 19939
backFunc_running yes
backFunc_start 2016-04-06 17:03:07
cpu_numcores 2
loadavg_15min 0.44
loadavg_1min 0.66
loadavg_5min 0.54
loadavg_active 1
loadavg_last_pid 20005
loadavg_process 650
random 3714432
uptime_graph_val 3600
uptime_idle 425499.43
uptime_up 495423.53
uptime_usage1sec 9.90
uptime_usage 57.06
uptime_useGraph 57.06 8.91 7.50 6.93 12.00 9.41 7.84 9.90 7.50 11.88 7.92 9.31
9.90
_
次に、1つの値を取得できます
_back_func get backFunc_pid newVar
echo $newVar
19939
_
またはquick cpグラフを作成します:
_lastMinuteGraph -p -o /tmp/lastMinuteGraph.png -W 640 -H 220
_
これにより、_uptime_graph_val
_値を持つ640x220PNGグラフィックがレンダリングされます。この場合、_back_func start
_が_-g 3600
_で1時間以上呼び出されたため、グラフィックは640列で3600ピーク、220行で0-100%を示しています。
(Nota:コマンドは元々lastMinuteGraph
という名前でした。これは60個の値を格納したばかりの最初のバージョンでしたが、現在は_uptime_graph_val
_の値の数をstore。_-g 3600
_引数を使用したので、このコマンドはlastHourGraph
)という名前にすることができます。
次に:
_back_func stop
back_func get backFunc_end
2019-01-02 16:35:00
_
Bashのマニュアルによると ここ 、
コマンドが制御演算子「&」によって終了した場合、シェルはサブシェルでコマンドを非同期的に実行します。
また、サブシェルで実行されるプロセスは親シェルの環境を変更できないため、実行しようとしていることは一時ファイル/名前付きパイプを介してのみ可能であると思います。または、アプローチを再考することもできます。
メインプロセス(main.shと呼びましょう)が定期的に実行される別のbashスクリプトである場合は、他のスクリプト(other.shと呼びましょう)に値をファイルに書き込む(このファイルをvalue.shと呼びましょう)ようにすることができます。 。
other.sh
#! /bin/bash
echo "SOME_VAR=42" > /tmp/value.sh
main.sh
#! /bin/bash
. /tmp/value.sh
# Now you can use SOME_VAR