从管道读取的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 ()
内部的变量更改或从中访问的其他函数有关,我使用了$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.
有人可以告诉我为什么读取退出时我的变量会神奇地重置吗?
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
.因为这涉及到管道,所以while read
循环实际上无法与脚本的其余部分在相同的bash进程中运行; bash必须产生一个子进程,以便它可以将find
的stdout连接到while
循环的stdin.
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屋!