从 shell 循环修改 .bashrc 变量

从 shell 循环修改 .bashrc 变量

因此我创建了这个循环~/.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中的变量fortest_var1主 shell 中的变量不同。唯一的联系是循环中的变量是用创建子 shell 时主 shell 中的当前变量的值初始化的。此后,每个变量都是独立的,不会影响其他变量。

这就是为什么当你test_var1在主 shell 中发生更改时子 shell 不会反映它的原因。

您不想在前台运行循环(没有&)。如果您这样做,则源的新 shell.bashrc将卡在循环中,并且永远不会到达给您提示的点。如果您设法打破循环并获得提示,那么循环将不复存在。

在 Bash 中,您无法“从 shell 中导出变量,使其在后台运行的循环中也发生变化”。一些想法:

  1. 使用常规文件代替变量。两个 shell 可以对同一个文件进行操作。您可以将信息作为文件的内容传递。在这里,由于您只需要一位信息(开/关),因此您可以将其作为文件的存在传递。有用的启动:myfile="$(mktemp)"在主 shell 中运行,因此它和稍后启动的子 shell 可以使用变量(实际上是两个相同且恒定的变量)来定位文件。

  2. 在子 shell 中设置traps,因此SIGUSR1子 shell在接收后会以test_var1一种方式更改其自身,在接收后会SIGUSR2以另一种方式更改变量。主 shell 应该记住子 shell 的 PID ( bckgrndPID=$!),当您想要更改状态时,您将记住kill -s USR1 "$bckgrndPID"等等。输入这些命令会很麻烦kill,因此您可能需要定义两个函数,如onoff

  3. 由于你需要使用函数,你可以通过另一种方法来简化事情:让on成为一个函数,如果后台进程尚未启动,则启动它;让off终止它。很简单:

    on () {
      [ "$bckgrndPID" ] && return 0
      while :; do
        echo "teststuff happening!"
        sleep 10
      done &
      bckgrndPID=$!
    }
    
    off () {
      [ "$bckgrndPID" ] && kill "$bckgrndPID"
      unset bckgrndPID
    }
    
  4. 关于你的计划:

    我的实际用途是查看终端上的电池寿命(即使在 TTY 上)。

    使用tmux及其状态行 (搜索它)。

相关内容