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

时间:2012-03-11 16:18:35

标签: linux bash shell unix scripting

作为示例,请考虑以下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
...

2 个答案:

答案 0 :(得分:7)

这是因为&为第一个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

答案 1 :(得分:5)

基本上,你无法直接在父shell中读取变量。

由于&,第一个循环在子shell中运行;子shell的内存完全独立于主shell的内存,并且没有办法(没有像在子shell上运行调试器那样可怕的事情)来访问子shell和&# #39;来自父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)。