繁体   English   中英

Bash:如何在循环中检索背景中的变量值

[英]Bash: How to retrieve a variable value inside a background while loop

作为示例,请考虑以下bash脚本。 有两个循环,第一个在后台执行,第二个循环打印myvar值:

#!/bin/bash

myvar=AAA

while true;
do
    sleep 3
    myvar=BBB
    sleep 3
    myvar=CCC
done &

while true;
do
    echo "${myvar}"
    sleep 1
done

我实际获得的输出:

AAA
AAA
AAA
...

我希望获得的输出:

AAA
BBB
CCC
BBB
CCC
...

这是因为&为第一个while循环创建了一个新的子shell。

我很确定你需要使用某种IPC来解决这个问题。 使用管道或命名管道来实现生产者/消费者设置是合理的。

一个粗略的例子:

#!/bin/bash

myvar=AAA

while true;
do
    sleep 3
    myvar_piped=BBB
    echo $myvar_piped # this goes to the pipe.
    sleep 1
done | # this connects the two loops.

while true;
do
    # if we consumed something (timeout=1) print it, else print our own variable.
    if read -t 1 myvar_piped #
    then
        echo "${myvar_piped}"
    else
        echo "${myvar}"
    fi  
done

输出:

AAA
AAA
AAA
BBB
AAA
AAA
AAA
AAA
BBB

实质上,您无法直接在父shell中读取变量。

第一个循环是在子shell中运行的,因为& ; 子shell的内存完全独立于主shell的内存,并且没有办法(没有像在子shell上运行调试器那样可怕的事情)从父shell访问子内存。

如果您可以修改子shell进程以每秒写入其变量的值,那么父级可能能够检测到它。 或者,如果子shell在每次更改变量时将变量写入具有已知名称的文件,那么您可以在父级中随意读取该文件:

#!/bin/bash

tmp=$(mktemp)

trap "rm -f $tmp; exit 1" 0 1 2 3 13 15

myvar=AAA
echo $myvar > $tmp

while true;
do
    sleep 3
    myvar=BBB
    echo $myvar > $tmp
    sleep 3
    myvar=CCC
    echo $myvar > $tmp
done &

while cat $tmp
do
    sleep 1
done

rm -f $tmp
trap 0

trappery确保在大多数情况下删除临时文件(信号HUP,INT,QUIT,PIPE和TERM)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM