![Zenity 进度条是否影响变量](https://linux22.com/image/1117844/Zenity%20%E8%BF%9B%E5%BA%A6%E6%9D%A1%E6%98%AF%E5%90%A6%E5%BD%B1%E5%93%8D%E5%8F%98%E9%87%8F.png)
大家好,我目前正在尝试将 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 while
zenity
gnome 帮助页面运行下面的脚本并查看结果,
#!/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"
我将增量改为i
10,i
用于增加进度条的增量并使sleep 1
进度可察觉。
观察:zenity
虽然弹出窗口 中显示该值会增加,但在终端上显示该值保持不变,i: 0 p: 0
希望这会有所帮助。
如何在外部使用子 shell 变量
父 shell 不能使用子 shell 中的变量。你可以找到有关 subshell 的更多信息请点击此处。但是你总是可以将变量从子 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