在从管道读取的 while 读取循环之后重置变量 [英] Variables getting reset after the while read loop that reads from a pipeline
问题描述
initiate () {
read -p "Location(s) to look for .bsp files in? " loc
find $loc -name "*.bsp" | while read
do
if [ -f "$loc.bz2" ]
then
continue
else
filcount=$[$filcount+1]
bzip $loc
fi
if [ "$scan" == "1" ]; then bzipint $loc
fi
echo $filcount #Correct counting
echo $zipcount #Correct counting
echo $scacount #Correct counting
echo $valid #Equal to 1
done
echo $filcount #Reset to 0
echo $zipcount #Reset to 0
echo $scacount #Reset to 0
echo $valid #Still equal to 1
}
我正在编写一个 bash shell 脚本来使用 bzip2
压缩目录中的所有 .bsp
文件.在这个脚本中,我有几个变量来计算总数(文件、成功的 zip 文件、成功的完整性扫描),但是我似乎遇到了一个问题.
I'm writing a bash shell script to use bzip2
to zip up all .bsp
files inside a directory. In this script I have several variables for counting totals (files, successful zips, successful integrity scans), however I seem to have run into a problem.
当 find $loc -name "*.bsp"
用完文件给 while read
和 while read
退出时,它将 $filcount
、$zipcount
和 $scacount
清零(所有这些都在 initiate()
、bzip()
(在initiate()
中调用)或bzipint()
(在initiate()中也调用)
).
When find $loc -name "*.bsp"
runs out of files to give the while read
and while read
exits, it zeros out $filcount
, $zipcount
and $scacount
(all of which are changed (increased) inside initiate ()
, bzip ()
(which is called during initiate ()
) or bzipint ()
(which is also called in initiate ()
).
为了测试它是否与initiate()
内部的变量变化或从它访问的其他函数有关,我使用了echo $valid
,它在外部定义initiate()
(如$filcount
、$zipcount
等),但不会从initiate()
或 initiate()
本身.
In order to test if it's something to do with variables changing inside initiate ()
or other functions accessed from it, I used echo $valid
, which is defined outside of initiate ()
(like $filcount
, $zipcount
, etc.), but is not changed from another function inside initiate ()
or inside initiate ()
itself.
有趣的是,$valid
不会像初始化中的其他变量一样被重置为 0.
Interestingly enough, $valid
does not get reset to 0 like the other variables inside initiate.
谁能告诉我为什么当 read 退出时我的变量会神奇地重置?
Can anyone tell me why my variables magically get reset when while read exits?
推荐答案
我昨天遇到了这个问题.
I ran into this problem yesterday.
问题是你在做 find $loc -name "*.bsp" |阅读时
.因为这涉及管道,while read
循环实际上不能与脚本的其余部分在同一个 bash 进程中运行;bash 必须产生一个子进程,以便它可以将 find
的标准输出连接到 while
循环的标准输入.
The trouble is that you're doing find $loc -name "*.bsp" | while read
. Because this involves a pipe, the while read
loop can't actually be running in the same bash process as the rest of your script; bash has to spawn off a subprocess so that it can connect the the stdout of find
to the stdin of the while
loop.
这一切都非常聪明,但这意味着循环中设置的任何变量在循环后都看不到,这完全违背了我编写的 while
循环的全部目的.
This is all very clever, but it means that any variables set in the loop can't be seen after the loop, which totally defeated the whole purpose of the while
loop I was writing.
您可以尝试在不使用管道的情况下将输入提供给循环,或者在不使用变量的情况下从循环中获取输出.我最终得到了一个可怕的可憎之处,涉及写入临时文件并将整个循环包装在 $(...)
中,如下所示:
You can either try to feed input to the loop without using a pipe, or get output from the loop without using variables. I ended up with a horrifying abomination involving both writing to a temporary file AND wrapping the whole loop in $(...)
, like so:
var="$(producer | while read line; do
...
echo "${something}"
done)"
这让我将 var 设置为从循环中回显的所有内容.我可能搞砸了那个例子的语法;我现在手边没有我写的代码.
Which got me var set to all the things that had been echoed from the loop. I probably messed up the syntax of that example; I don't have the code I wrote handy at the moment.
这篇关于在从管道读取的 while 读取循环之后重置变量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!