问题描述
我要计算给定目录中的所有*二进制文件。起初,我正在同一个 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循环壳层困境的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!