Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
perl上的rysnc,直到循环永不中断_Perl - Fatal编程技术网

perl上的rysnc,直到循环永不中断

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

我在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 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';
我的$