gpt4 book ai didi

bash后台进程修改全局变量

转载 作者:行者123 更新时间:2023-11-29 08:42:53 25 4
gpt4 key购买 nike

在我的 Bash 脚本中,我有一个全局变量 foo 设置为某个值和一个在后台运行的函数进程 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

如何让 globalback 行都以 1 结尾?换句话说,如何让主进程获取后台进程对 foo 的修改?

最佳答案

升级2019

使用 bash_ipc_demo 添加补全和图形生成器。

约会

如果你想有两个可以通信的独立进程,你必须在两个进程都可以到达的地方放置一个会合点

这可以是一个简单的文件、一个 fifo 管道、一个 unix 套接字、一个 TCP 套接字或其他(Rexx 端口)。

及其他

Bash 没有与 rexx 端口等效的端口,因此有一个使用 rendez-vous 文件的小示例(在我的 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]}
}

将需要 --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_demobash_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

然后,你可以获得一个值

back_func get backFunc_pid newVar
echo $newVar
19939

或者构建一个快速 cpu 图表:

lastMinuteGraph -p -o /tmp/lastMinuteGraph.png -W 640 -H 220

这将呈现一个 640x220 PNG 图形,具有 uptime_graph_val 值。在这种情况下,因为 back_func start 是用 -g 3600 从 more超过一小时,图形在 640 列上显示 3600 peek,在 220 行上显示 0-100%:

LastHourGraph

(注意: 命令最初命名为 lastMinuteGraph,因为它的第一个版本只存储了 60 个值,现在使用 uptime_graph_val/em> 用于存储值的数量。因为我使用了 -g 3600 参数,所以这个命令可以命名为 lastHourGraph)。

然后:

back_func stop  
back_func get backFunc_end
2019-01-02 16:35:00

关于bash后台进程修改全局变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13207292/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com