Bash 循环比较文件
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/12413097/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Bash loop to compare files
提问by cbcp
I'm obviously missing something simply, and know the problem is that it's creating a blank output which is why it can't compare. However if someone could shed some light on this it would be great - I haven't isolated it.
我显然只是遗漏了一些东西,并且知道问题在于它正在创建一个空白输出,这就是它无法比较的原因。但是,如果有人可以对此有所了解,那就太好了-我没有将其隔离。
Ultimately, I'm trying to compare the md5sumfrom a list stored in a txt file, to that stored on the server. If errors, I need it to report that. Here's the output:
最终,我试图将md5sum存储在 txt 文件中的列表与存储在服务器上的列表进行比较。如果有错误,我需要它来报告。这是输出:
root@vps [~/testinggrounds]# cat md5.txt | while read a b; do
> md5sum "$b" | read c d
> if [ "$a" != "$c" ] ; then
> echo "md5 of file $b does not match"
> fi
> done
md5 of file file1 does not match
md5 of file file2 does not match
root@vps [~/testinggrounds]# md5sum file*
2a53da1a6fbfc0bafdd96b0a2ea29515 file1
bcb35cddc47f3df844ff26e9e2167c96 file2
root@vps [~/testinggrounds]# cat md5.txt
2a53da1a6fbfc0bafdd96b0a2ea29515 file1
bcb35cddc47f3df844ff26e9e2167c96 file2
采纳答案by David W.
I'm not going to argue. I simply try to avoid double read from inside loops.
我不打算争论。我只是尽量避免从内部循环中进行双重读取。
#! /bin/bash
cat md5.txt | while read sum file
do
prev_sum=$(md5sum $file | awk '{print }')
if [ "$sum" != "$prev_sum" ]
then
echo "md5 of file $file does not match"
else
echo "$file is fine"
fi
done
回答by themel
回答by jordanm
The problem that you are having is that your inner read is executed in a subshell. In bash, a subshell is created when you pipe a command. Once the subshell exits, the variables $c and $d are gone. You can use process substitution to avoid the subshell:
您遇到的问题是您的内部读取是在子外壳中执行的。在 bash 中,当您通过管道传输命令时会创建一个子 shell。一旦子shell退出,变量$c和$d就消失了。您可以使用进程替换来避免子shell:
while read -r -u3 sum filename; do
read -r cursum _ < <(md5sum "$filename")
if [[ $sum != $cursum ]]; then
printf 'md5 of file %s does not match\n' "$filename"
fi
done 3<md5.txt
The redirection 3<md5.txtcauses the file to be opened as file descriptor 3. The -u 3option to readcauses it to read from that file descriptor. The inner readstill reads from stdin.
重定向3<md5.txt导致文件作为文件描述符 3 打开。-u 3选项使其read从该文件描述符中读取。内部read仍然从标准输入读取。

