从管道读取的while读取循环后,变量将重置 [英] Variables getting reset after the while read loop that reads from a pipeline

查看:213
本文介绍了从管道读取的while读取循环后,变量将重置的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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 readwhile 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆