perl上的rysnc,直到循环永不中断
我在perl脚本方面遇到了困难。我有一个脚本,它包含一个循环,但一旦退出状态为零,它就不会中断。只有在“if”语句最初检查退出状态结果为1时,循环才会运行perl上的rysnc,直到循环永不中断,perl,Perl,我在perl脚本方面遇到了困难。我有一个脚本,它包含一个循环,但一旦退出状态为零,它就不会中断。只有在“if”语句最初检查退出状态结果为1时,循环才会运行 my $a = "/home/vivek/generated_mdsum_reference.out"; my $b = "/home/vivek/generated_mdsum_new.out"; sub CHECK { print "\n"; print "\n"; print "\n\tGenerating M
my $a = "/home/vivek/generated_mdsum_reference.out";
my $b = "/home/vivek/generated_mdsum_new.out";
sub CHECK {
print "\n";
print "\n";
print "\n\tGenerating MD5SUM ....";
my $dumpfile = "/home/vivek/file_dump.dmp";
print "\n";
# my $md5sum = system("md5sum $dumpfile");
my $md5sum = `md5sum $dumpfile`;
print "\n";
print "\nChecksum: $md5sum.";
# Put checksum in file
my $ochksumfile = "/home/vivek/generated_mdsum_new.out";
open (my $fh, '>', "$ochksumfile") or die "no file:$!";
my $output = $md5sum;
die "$!" if $?;
$value = (split / /, "$output")[0];
print $fh $value;
my $status =compare($b, $a);
}
my $status =compare($b, $a);
if ( $status == 1 ){
do
CHECK;
until ($status == 0 ) {
print "\n\tfiles are now Ok. Exiting..";
print "\n\t";
}
我在那里设置的所有变量都运行良好,我只在直到循环中结束,它一直在无休止地运行,我认为它在函数“CHECK”的其余部分之前无法通过
伙计们,请帮帮我。我不明白为什么until循环应该停止 简言之,您在“检查”子目录中获得一个文件的md5总和 现在比较$a和$b并返回结果。 假设$a/$b包含一些有用的内容,在我看到的until块或CHECK块中也没有更改的内容,因此比较将继续返回相同的结果(假设“compare”比较并且没有更改任何内容,如果它更改了,那么这将是一个不好的命名)
因此,在until块中,做一些事情来影响检查,否则您将陷入循环。让我们看看有问题的块
my $status = compare($b, $a);
if ( $status == 1 ) {
do
CHECK;
until ($status == 0 ) {
print "\n\tfiles are now Ok. Exiting..";
print "\n\t";
}
不管你是不是认真的,这相当于
my $status = compare($b, $a);
if ( $status == 1 ) {
do CHECK;
until ( $status == 0 ) {
print "\n\tfiles are now Ok. Exiting..";
print "\n\t";
}
因此,until
循环的内容只是两个print语句,它们不会改变$status
的值,因此它将永远循环
我想你的意思是
my $status = compare($b, $a);
if ( $status == 1 ) {
do {
CHECK;
} until $status == 0;
print "\n\tfiles are now Ok. Exiting..";
print "\n\t";
}
它将反复调用检查
,直到$status
设置为零
除了您应该在本地标识符中始终使用小写字符。大写保留用于全局标识符,如包名称。在这种情况下,您无意中创建了一个检查
块
这么说
在运行的Perl程序开始和结束时执行五个特别命名的代码块。这些是BEGIN
、UNITCHECK
、CHECK
、INIT
和END
块
这些代码块可以以sub作为前缀,以显示子例程的外观(尽管这不是好的样式)。应该注意的是,这些代码块并不是真正以命名子例程的形式存在的(尽管它们的外观如此)。事实上,一个程序中可以有多个这样的代码块,它们会在适当的时候被执行。因此,您不能按名称执行任何这些代码块
因此,由于“这些代码块实际上并不作为命名的子例程存在”,您的程序在编译期间只会调用CHECK
,随后的显式调用将被忽略
因此,将您的子例程重命名为check
,并将您的代码更改为
my $status = compare($b, $a);
if ( $status == 1 ) {
do {
CHECK;
} until $status == 0;
print "\n\tfiles are now Ok. Exiting..";
print "\n\t";
}
一切都会好的您应该在本地标识符中始终使用小写字符。大写保留用于全局标识符,如包名称。在这种情况下,您无意中创建了一个检查
块
这么说
在运行的Perl程序开始和结束时执行五个特别命名的代码块。这些是BEGIN
、UNITCHECK
、CHECK
、INIT
和END
块
这些代码块可以以sub作为前缀,以显示子例程的外观(尽管这不是好的样式)。应该注意的是,这些代码块并不是真正以命名子例程的形式存在的(尽管它们的外观如此)。事实上,一个程序中可以有多个这样的代码块,它们会在适当的时候被执行。因此,您不能按名称执行任何这些代码块
因此,由于“这些代码块实际上并不作为命名的子例程存在”,您的程序在编译期间只会调用CHECK
。这意味着对CHECK的显式调用将被忽略,$status
永远不会更改
将子程序更改为检查
,一切都会好起来问题在这里:
until ($status == 0 ) {
print "\n\tfiles are now Ok. Exiting..";
print "\n\t";
}
循环中没有任何地方可以更改$status
的值
“do CHECK;”
不是循环的一部分。将根据
CHECK
sub的返回值的名称来评估文件如果它真的叫那个潜艇的话。
它不会,因为它实际上不是一个子程序
until
的另一种形式是:
do {
CHECK; # doesn't work as this is a special name
} until $status == 0;
print "\n\tfiles are now Ok. Exiting..";
print "\n\t";
这仍然是一个问题,因为CHECK
是一个块的特殊名称,它在检查时只被调用一次,您实际上无法调用它
另外,CHECK
中的代码总是有相同的结果,因此重复调用它是没有意义的,如果它第一次不工作,仍然可能导致无限循环
我可能就是这样写的 这是使您的代码对我有意义的第一步,同时也修复了上面指出的一些错误 我还将
$a
和$b
更改为$ref
和$new
,因为$a
和$b
是保留变量
#! /usr/bin/env perl
use strict;
use warnings;
use 5.10.1; # set minimum version which was released in 2009
use autodie;
use File::Spec::Functions qw' catfile catdir rootdir curdir ';
use Digest::MD5;
use File::Compare qw' compare ';
# should be // not ||, but it will work if your dir isn't named "0" or ""
my $basedir = $ENV{HOME} || catdir rootdir, qw' home vivek ';
# try the current directory if it doesn't exist
$basedir = curdir unless -d $basedir;
my $ref = catfile $basedir, 'generated_mdsum_reference.out';
my $new = catfile $basedir, 'generated_mdsum_new.out';
my $dumpfile = catfile $basedir, 'file_dump.dmp';
# forward declare so that we can put them at the end
sub md5_hex_file;
sub md5_sum;
sub check;
#-------------------------------------------------------
if ( compare($new, $ref) != 0 ){
if ( check($dumpfile,$new) == 0 ){
print "\n\tfiles are now Ok. Exiting..\n";
} else {
local $| = 1; # make sure the output is flushed to STDOUT
print "\n\tfiles are NOT OK. Exiting..\n";
exit 1;
}
}
#-------------------------------------------------------
# helper subroutines
sub md5_hex_file {
my ($filename) = @_;
# let Digest::MD5 read the file for us
my $ctx = Digest::MD5->new;
{ # limit scope of $fh
open my $fh, '<', $filename;
binmode $fh;
$ctx->addfile( $fh );
close $fh;
}
$ctx->hexdigest;
}
# no longer necessary
sub md5_sum {
my ($filename) = @_;
# `md5sum -b $filename`
md5_hex_file($filename) . " $filename\n";
}
sub check {
my ( $infile, $outfile ) = @_
print "\n" x 3, "\tGenerating MD5SUM ....\n";
my $md5_hex = md5_hex_file $infile;
print "\n" x 2, "Checksum: $md5_hex.\n";
# Put checksum in file
{
open my $out_fh, '>', $outfile;
print {$out_fh} $md5_hex;
close $out_fh;
}
my $status = compare $new, $ref;
return $status if $status == 0;
# add a newline and hope that fixes it
{
open my $out_fh, '>>', $outfile;
print {$out_fh} "\n";
close $out_fh;
}
return compare $new, $ref;
}
我使用Perl附带的模块对其进行了改进,这样我就不必检查open()
和close()
()的返回值,也不必依赖特定平台的约定(,和)
我想你已经上膛了
我从检查
子项中删除了$status
的设置,以减少全局变量的使用
#! /usr/bin/env perl
use strict;
use warnings;
use 5.10.1; # set minimum version which was released in 2009
use autodie;
use File::Spec::Functions qw' catfile catdir rootdir curdir ';
use Digest::MD5;
use File::Compare qw' compare ';
# should be // not ||, but it will work if your dir isn't named "0" or ""
my $basedir = $ENV{HOME} || catdir rootdir, qw' home vivek ';
# try the current directory if it doesn't exist
$basedir = curdir unless -d $basedir;
my $ref = catfile $basedir, 'generated_mdsum_reference.out';
my $new = catfile $basedir, 'generated_mdsum_new.out';
my $dumpfile = catfile $basedir, 'file_dump.dmp';
# forward declare so that we can put them at the end
sub md5_hex_file;
sub md5_sum;
sub check;
#-------------------------------------------------------
if ( compare($new, $ref) != 0 ){
if ( check($dumpfile,$new) == 0 ){
print "\n\tfiles are now Ok. Exiting..\n";
} else {
local $| = 1; # make sure the output is flushed to STDOUT
print "\n\tfiles are NOT OK. Exiting..\n";
exit 1;
}
}
#-------------------------------------------------------
# helper subroutines
sub md5_hex_file {
my ($filename) = @_;
# let Digest::MD5 read the file for us
my $ctx = Digest::MD5->new;
{ # limit scope of $fh
open my $fh, '<', $filename;
binmode $fh;
$ctx->addfile( $fh );
close $fh;
}
$ctx->hexdigest;
}
# no longer necessary
sub md5_sum {
my ($filename) = @_;
# `md5sum -b $filename`
md5_hex_file($filename) . " $filename\n";
}
sub check {
my ( $infile, $outfile ) = @_
print "\n" x 3, "\tGenerating MD5SUM ....\n";
my $md5_hex = md5_hex_file $infile;
print "\n" x 2, "Checksum: $md5_hex.\n";
# Put checksum in file
{
open my $out_fh, '>', $outfile;
print {$out_fh} $md5_hex;
close $out_fh;
}
my $status = compare $new, $ref;
return $status if $status == 0;
# add a newline and hope that fixes it
{
open my $out_fh, '>>', $outfile;
print {$out_fh} "\n";
close $out_fh;
}
return compare $new, $ref;
}
#/usr/bin/env perl
严格使用;
使用警告;
使用5.10.1;#设置2009年发布的最低版本
使用自动模具;
使用File::Spec::函数qw'catfile catdir rootdir curdir';
使用Digest::MD5;
使用文件::Compare qw'Compare';
#应该是//not | |,但如果您的目录未命名为“0”或“”
my$basedir=$ENV{HOME}| | catdir rootdir,qw‘HOME vivek’;
#如果当前目录不存在,请尝试该目录
$basedir=curdir,除非-d$basedir;
my$ref=catfile$basedir,'generated_mdsum_reference.out';
我的$