Zenity 进度条是否影响变量

Zenity 进度条是否影响变量

大家好,我目前正在尝试将 zenity 进度条实现到我的 while 循环中,但是我注意到我原本应该增加的变量并没有增加。这是我尝试的一个示例测试脚本:

i=0
p=0

while [ $i -lt 10 ]
do
      i=$[$i + 1]
      echo $i
      p=$[$p + 1]
done | (zenity --progress --title="test" --text="test")
echo "i: $i p: $p"

我注意到进度条工作正常,但是p用作计数器的变量受到了 zenity 的影响。我的代码有问题吗?变量i用于回显值以移动进度条,而变量p用于其他目的。尽管在 while 循环中将其递增,p但和的值i都是。0

我希望有一种方法可以在不删除 zenity 进度条的情况下使变量p增加i。但我不确定为什么在(zenity --progress --title="test" --text="test")删除该行后变量的增加仍然有效

添加

进度条结束后如何使用变量i和?还有一个问题,是否需要用 括住 while 循环?p()

谢谢你的帮助!

答案1

增量,一切似乎都很好。但所有增量都在传递给的子 shell 内进行zenity。这就是为什么您在子 shell 外执行更改时无法获得更改的原因。我正在使用您的脚本,只添加了一些内容以在弹出窗口上打印循环echo内的变量。要了解有关 zenity 进度对话框语法的更多信息,请参阅do whilezenitygnome 帮助页面运行下面的脚本并查看结果,

#!/bin/bash
i=0
p=0
(while [ $i -lt 100 ]
do
    i=$[$i + 10]
    echo $i ; sleep 1
    echo "#  now i is $i and p=$p"
    p=$[$p + 1]
done) | zenity --progress --title="test" --text="test"
echo "i: $i p: $p"

我将增量改为i10,i用于增加进度条的增量并使sleep 1进度可察觉。

观察:zenity虽然弹出窗口 中显示该值会增加,但在终端上显示该值保持不变,i: 0 p: 0

zenity 窗口

希望这会有所帮助。

如何在外部使用子 shell 变量

父 shell 不能使用子 shell 中的变量。你可以找到有关 subshel​​l 的更多信息请点击此处。但是你总是可以将变量从子 shell 写入临时文件,以供其父级读取。这可能不是最好的方法,但它确实有效。

#!/bin/bash
..
(while [ $i -lt 100 ]
do
    ...
    ...
done
echo "p=$(echo $p)" > tmp
echo "i=$(echo $i)" >> tmp
) | zenity --progress --title="test" --text="test"
. tmp
rm tmp
echo "i: $i p: $p"

现在它将像下面这样显示在终端中,i: 100 p: 10因此您可以随意使用它们。正如您在上一部分中问到的那样,它不是 while 循环,而是子 shell。习惯上将子 shell 的内容放在括号内。

答案2

进程替换可以防止创建烦人的子shell,但是语法有点奇怪:

$ k=0; for x in a b; do ((k++)); done | zenity --progress; echo "$k"

→ 0(不好)

$ k=0; for x in a b; do ((k++)); done > >(zenity --progress); echo "$k"

→ 2 (确定)

我喜欢这一点,因为您通常不需要对脚本进行大量修改即可使其正常工作。但是,一些奇特的 shell 可能缺少此功能。对于 Bash,请查看手册中的“进程替换”部分。

使用更接近最初问题中的示例的代码:

  i=0
  p=0

  while [ $i -lt 10 ]
  do
        i=$[$i + 1]
        echo $((10 * i))
        sleep 0.1
        p=$[$p + 1]
  done > >(zenity --progress --title="test" --text="test")
  echo "i: $i p: $p"

(我添加了睡眠以使进度更加明显,并且我回显十次以在到达循环结束时i获得一个。)100

相关内容