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