如何查看Perl系统命令中的错误?

xmd2e60i  于 2022-11-15  发布在  Perl
关注(0)|答案(2)|浏览(176)

我正在运行这段Perl脚本:

system "bash", "-c",
" some command; exit \${PIPESTATUS[0]}"
and die "has failed"

现在,如果some command没有正确执行,则脚本将失败,并且has failed没有任何有用的信息。
如何让die命令打印some command生成的任何错误消息?

vaqhlq81

vaqhlq811#

大概是这样的:

system($cmd) == 0 or die "$0: [$cmd] failed: $?\n";

另请参见Perl错误变量。

iih3973s

iih3973s2#

这里的问题是,您希望看到一个命令的结果,该命令位于提供您可以检查的内容的命令之前。沿着,您正在运行的命令是bash。但是,我认为您可能不需要exit命令,因为您已经可以从Perl的一个错误变量中获得该信息。
下面的程序通过system运行一些东西,并查看各种错误变量(您可以在perlvar中阅读更多信息)。我也在Mastering Perl中写了更多关于这方面的内容:

  • $!是perl试图执行命令时出现的错误。它也是一个“dualvar”,意味着它有不同的字符串和数字值。
  • $?是关闭管道的状态(它还包括我们认为是命令的退出值)
  • $^E是额外的操作系统特定信息,在非Unix环境中很有用,包括Windows。

这里有一个程序来尝试一些事情与系统然后检查各种错误变量。

#!perl
use v5.26;

my @runs = (
    [ "false" ],
    [ "/etc/hosts" ],
    [ "not_a_command" ],
    [ "bash" , "-c", "not_a_command" ],
    [ "bash" , "-c", "not_a_command; exit 73" ],
    [ "bash" , "-c", "false" ],
    [ "bash" , "-c", "false; exit 37" ],
    );

foreach my $run ( @runs ) {
    my $exit_code = system { $run->[0] } @$run;
    dump_error( $run, $exit_code, $!, $?, $^E );
    }

sub dump_error {
    my( $label, $exit_code, $system_error, $pipe_status, $os_info ) = @_;

    my $system_error_num = $system_error + 0;
    my $system_error_string = $system_error . '';

    my $pipe_binary = sprintf '%016b', $pipe_status;

    my $pipe_exit   = $pipe_status >> 8;
    my $pipe_signal = $pipe_status & 127;
    my $pipe_core   = $pipe_status & 128;

    print <<~"HERE"
    --- @$label ---
        exit:   $exit_code
        system:
          number: $system_error_num
          string: $system_error_string
        pipe:   $pipe_status ($pipe_binary)
          exit:   $pipe_exit
          signal: $pipe_signal
          core:   $pipe_core
        os:     $os_info
    HERE
    }

下面是输出,我将用一些注解来打断它:
只运行false,退出时返回1。将其上移8位,得到256。但没有错误:程序做了它应该做的事情”

--- false ---
    exit:   256
    system:
      number: 0
      string:
    pipe:   256 (0000000100000000)
      exit:   1
      signal: 0
      core:   0
    os:

尝试运行/etc/hosts是一个错误,它是一个不可执行的普通文件。system根本无法启动程序。注意$!现在有一个数字和字符串值。另外,退出代码是-1,这意味着system无法启动程序。不要担心那一长串的1,这只是来自64位系统上-1一个产物:

--- /etc/hosts ---
    exit:   -1
    system:
      number: 13
      string: Permission denied
    pipe:   -1 (1111111111111111111111111111111111111111111111111111111111111111)
      exit:   72057594037927935
      signal: 127
      core:   128
    os:     Permission denied

下一个几乎和/etc/hosts一样,但这次文件不存在。system又一次无法启动命令,因此返回-1$!中的值有不同的错误:

--- not_a_command ---
    exit:   -1
    system:
      number: 2
      string: No such file or directory
    pipe:   -1 (1111111111111111111111111111111111111111111111111111111111111111)
      exit:   72057594037927935
      signal: 127
      core:   128
    os:     No such file or directory

下面我们来看看您的问题。这个问题试图运行一个不存在的文件,但这次system可以运行bash,因此各种错误值略有不同。$!的结果与上一次相同

--- bash -c not_a_command ---
    exit:   32512
    system:
      number: 2
      string: No such file or directory
    pipe:   32512 (0111111100000000)
      exit:   127
      signal: 0
      core:   0
    os:     No such file or directory

现在,再扩展一步,以获得您所拥有的:一个复合命令。第一个命令将失败,但bash会继续运行exit。最后一个命令将设置Perl的错误值中的值:

--- bash -c not_a_command; exit 73 ---
    exit:   18688
    system:
      number: 2
      string: No such file or directory
    pipe:   18688 (0100100100000000)
      exit:   73
      signal: 0
      core:   0
    os:     No such file or directory
--- bash -c false ---
    exit:   256
    system:
      number: 2
      string: No such file or directory
    pipe:   256 (0000000100000000)
      exit:   1
      signal: 0
      core:   0
    os:     No such file or directory
--- bash -c false; exit 37 ---
    exit:   9472
    system:
      number: 2
      string: No such file or directory
    pipe:   9472 (0010010100000000)
      exit:   37
      signal: 0
      core:   0
    os:     No such file or directory
bash: not_a_command: command not found
bash: not_a_command: command not found

相关问题