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

查看:30
本文介绍了在从管道读取的 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()内部的变量变化或从它访问的其他函数有关,我使用了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屋!

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