因此我创建了这个循环~/.bashrc
:
export test_var1=TRUE
for (( a=0;a<1;a )); do
if [[ $test_var1 == "TRUE" ]]; then
sleep 1
echo "teststuff happening! test_var1=${test_var1}"
sleep 10
fi
done &
并且它达到了预期的效果,echo "teststuff...
我的终端上每 11 秒就会回显一次:
me@yes:~$ teststuff happening! test_var1=TRUE
teststuff happening! test_var1=TRUE
teststuff happening! test_var1=TRUE
teststuff happening! test_var1=TRUE
teststuff happening! test_var1=TRUE
teststuff happening! test_var1=TRUE
teststuff happening! test_var1=TRUE
teststuff happening! test_var1=TRUE
teststuff happening! test_var1=TRUE
teststuff happening! test_var1=TRUE
但是当我尝试改变变量时,它并没有生效:
me@yes:~$ teststuff happening! test_var1=TRUE
test_var1=no
me@yes:~$ teststuff happening! test_var1=TRUE
export test_var1=no
me@yes:~$ teststuff happening! test_var1=TRUE
我如何从我的 shell 中导出一个变量,以便它也在正在运行的循环中发生变化~/.bashrc
?
我的实际用途是查看终端上的电池寿命(即使在 TTY 上)。
答案1
for … do … done &
由于 ,代码在后台运行&
。在后台运行的 Shell 代码在子 Shell 中运行。此类子 Shell 继承了变量 (甚至未出口的),但它将它们作为副本而不是引用继承。因此,循环test_var1
中的变量for
与test_var1
主 shell 中的变量不同。唯一的联系是循环中的变量是用创建子 shell 时主 shell 中的当前变量的值初始化的。此后,每个变量都是独立的,不会影响其他变量。
这就是为什么当你test_var1
在主 shell 中发生更改时子 shell 不会反映它的原因。
您不想在前台运行循环(没有&
)。如果您这样做,则源的新 shell.bashrc
将卡在循环中,并且永远不会到达给您提示的点。如果您设法打破循环并获得提示,那么循环将不复存在。
在 Bash 中,您无法“从 shell 中导出变量,使其在后台运行的循环中也发生变化”。一些想法:
使用常规文件代替变量。两个 shell 可以对同一个文件进行操作。您可以将信息作为文件的内容传递。在这里,由于您只需要一位信息(开/关),因此您可以将其作为文件的存在传递。有用的启动:
myfile="$(mktemp)"
在主 shell 中运行,因此它和稍后启动的子 shell 可以使用变量(实际上是两个相同且恒定的变量)来定位文件。在子 shell 中设置
trap
s,因此SIGUSR1
子 shell在接收后会以test_var1
一种方式更改其自身,在接收后会SIGUSR2
以另一种方式更改变量。主 shell 应该记住子 shell 的 PID (bckgrndPID=$!
),当您想要更改状态时,您将记住kill -s USR1 "$bckgrndPID"
等等。输入这些命令会很麻烦kill
,因此您可能需要定义两个函数,如on
和off
。由于你需要使用函数,你可以通过另一种方法来简化事情:让
on
成为一个函数,如果后台进程尚未启动,则启动它;让off
终止它。很简单:on () { [ "$bckgrndPID" ] && return 0 while :; do echo "teststuff happening!" sleep 10 done & bckgrndPID=$! } off () { [ "$bckgrndPID" ] && kill "$bckgrndPID" unset bckgrndPID }
关于你的计划:
我的实际用途是查看终端上的电池寿命(即使在 TTY 上)。
使用
tmux
及其状态行 (搜索它)。