Bash脚本:While-Loop子壳困境

我想计算一个给定目录内的所有* bin文件。 最初我正在使用一个for-loop

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

但是,在某些目录中有太多的文件导致错误: Argument list too long

因此,我正在用一个pipe道while-loop尝试它:

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

现在的问题是通过使用pipe子的子壳来创build。 因此, echo $var返回0
我该如何处理这个问题呢?
原来的代码:

 #!/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 

问题是while循环在子shell中执行。 在while循环终止之后, var的副本的副本被丢弃,并且回显父值(其值不变)的原始var

解决这个问题的一个方法是使用Process Substitution ,如下所示:

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

看看BashFAQ / 024的其他解决方法。

注意我也用lsreplace了ls ,因为parsingls不是好习惯。

符合POSIX标准的解决scheme是使用pipe道(p文件)。 这个解决scheme非常好,便携和POSIX,但是在硬盘上写了一些东西。

 mkfifo mypipe find . -type f -name "*.bin" -maxdepth 1 > mypipe & while read line do # action done < mypipe rm mypipe 

您的pipe道是您的硬盘上的文件。 如果你想避免有无用的文件,不要忘记删除它。

这也可以用for循环来完成:

 var=0; for file in `find . -type f -name "*.bin" -maxdepth 1`; do # perform computations on "$i" ((var++)) done echo $var