本文介绍了bash脚本:while循环壳层困境的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我要计算给定目录中的所有*二进制文件。起初,我正在同一个 for循环

  VAR = 0
因为我在1!*斌

   在$ I进行计算....
   VAR + = 1
DONE
回声是$ var

然而,在某些目录中有导致错误的文件太多:参数列表太长

所以,我是用管道尝试它 while循环

  VAR = 0
LS * .bin文件|而读我;

  在执行$ I计算
  VAR + = 1
DONE
回声是$ var

现在的问题是通过创建子shell管道。因此,回声是$ var 收益 0 。结果
我该如何处理这个问题?结果
原来的code:

 #!/斌/庆典功能entropyImpl {
    如果[-n$ 1]
    然后
        如果[[-e$ 1]
        然后
            回声规模= 4; $(gzip的-c $ {1} |厕所-c)/ $(猫$ {1} |厕所-c)|公元前
        其他
            回声文件($ 1)未找到
        科幻
    其他
        数据文件=$(mktemp的entropy.XXXXX)
        猫 - > $ datafile中
        熵$ datafile中
        RM$ datafile中
    科幻    返回1
}
声明acc_entropy = 0
申报数量= 0LS * .bin文件|而读我;

    回声计算$ I|三通-a entropy.txt
    curr_entropy =`$ entropyImpl i`
    curr_entropy =`回声$ curr_entropy | bc`
    回声-e\\ tEntropy:$ curr_entropy|三通-a entropy.txt
    acc_entropy =`回声$ acc_entropy + $ curr_entropy | bc`
    让数+ = 1
DONE回声失去作用:$算| $ acc_entropy
acc_entropy =`回声规模= 4; $ acc_entropy / $伯爵| bc`回声-e============================================== ===== \\ N|三通-a entropy.txt
回声-e累计熵:\\ T $ acc_entropy($计数文件处理)\\ n|三通-a entropy.txt


解决方案

的问题是,while循环是在子shell执行。 while循环结束后, VAR 的子shell的副本被丢弃,而原 VAR 父(其值不变)的呼应。

解决这个问题的方法之一是使用如下图所示:

  VAR = 0
而读我;

  #上执行$ I计算
  ((VAR ++))
完成< ≤(发现型的F -name* .BIN-maxdepth 1)。

看看获取其他解决方法。

请注意,我也取代 LS 找到,因为它不是好的做法的。

i want to compute all *bin files inside a given directory. Initially I was working with a for-loop:

var=0
for i in *ls *bin
do
   perform computations on $i ....
   var+=1
done
echo $var

However, in some directories there are too many files resulting in an error: Argument list too long

Therefore, I was trying it with a piped while-loop:

var=0
ls *.bin | while read i;
do
  perform computations on $i
  var+=1
done
echo $var

The problem now is by using the pipe subshells are created. Thus, echo $var returns 0.
How can I deal with this problem?
The original Code:

#!/bin/bash

function entropyImpl {
    if [[ -n "$1" ]]
    then
        if [[ -e "$1" ]]
        then
            echo "scale = 4; $(gzip -c ${1} | wc -c) / $(cat ${1} | wc -c)" | bc
        else
            echo "file ($1) not found"
        fi
    else
        datafile="$(mktemp entropy.XXXXX)"
        cat - > "$datafile"
        entropy "$datafile"
        rm "$datafile"
    fi

    return 1
}
declare acc_entropy=0
declare count=0

ls *.bin | while read i ;
do
    echo "Computing $i"  | tee -a entropy.txt
    curr_entropy=`entropyImpl $i`
    curr_entropy=`echo $curr_entropy | bc`
    echo -e "\tEntropy: $curr_entropy"  | tee -a entropy.txt
    acc_entropy=`echo $acc_entropy + $curr_entropy | bc`
    let count+=1
done

echo "Out of function: $count | $acc_entropy"
acc_entropy=`echo "scale=4; $acc_entropy / $count" | bc`

echo -e "===================================================\n" | tee -a entropy.txt
echo -e "Accumulated Entropy:\t$acc_entropy ($count files processed)\n" | tee -a entropy.txt
解决方案

The problem is that the while loop is executed in a subshell. After the while loop terminates, the subshell's copy of var is discarded, and the original var of the parent (whose value is unchanged) is echoed.

One way to fix this is by using Process Substitution as shown below:

var=0
while read i;
do
  # perform computations on $i
  ((var++))
done < <(find . -type f -name "*.bin" -maxdepth 1)

Take a look at BashFAQ/024 for other workarounds.

Notice that I have also replaced ls with find because it is not good practice to parse ls.

这篇关于bash脚本:while循环壳层困境的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-24 02:26