【问题标题】:perl - using backticks instead of system()perl - 使用反引号而不是 system()
【发布时间】:2012-06-07 21:27:02
【问题描述】:

我有一个 perl 脚本,它使用 system() 调用另一个 perl 脚本

就像:

my $returnval= system("perl", $path,$val1, $val2,@myarray);

因为 system() 只返回退出状态,但我希望脚本的输出使用反引号。

我尝试过类似的方法:

my $returnval = `$path`;

如何添加脚本应该接收的参数?

其他 perl 脚本的返回码应该是怎样的?目前是这样的

exit ($myreturnedvalue);

(如何)是否可以返回多个值?

【问题讨论】:

  • 很遗憾,我不明白关于返回多个值的问题。你能澄清一下吗?
  • 我想调用一个带参数的脚本,然后我想要脚本的输出和这个输出,它必须是一个值还是可以是一个数组或两个参数,如 exit (x1,x2 )
  • 只能返回一段文本(或二进制数据)。如果您想要多个值,那么您正在调用的脚本需要返回您在 Perl 中解析的序列化数据结构(空格分隔、JSON、XML 等)。
  • 啊,好的,所以我必须处理文本以提取我想要的信息,谢谢:)
  • 您是否想在程序中的多个文件中包含 perl 函数,或者您是否正在努力理解如何在程序中使用$?$output = ˋcmd arg1 arg2ˋ; $status = $?; 分别获取输出和状态。

标签: perl system return-value backticks


【解决方案1】:

通过 shell 将数据从一个 perl 脚本移动到另一个不是最佳解决方案。您应该知道反引号或qx() 会捕获打印到 STDOUT 的任何内容。从其他脚本中使用exit ($var) 不太可能被正确捕获。你需要print $var。但不要那样做。

相反,将其他脚本制作成一个模块并直接使用子例程。这是一个简单的例子:

在 bar.pm 中:

use strict;
use warnings;

package bar;  # declare our package

sub fooz {             # <--- Our target subroutine
    my $in = shift;    # passing the input
    return $in * 5;    # return value
}
1; # return value must be true

在 main.pl 中:

use strict;
use warnings;
use bar;   # bar.pm must be in one path in @INC

my $foo = bar::fooz(12);  # calling fooz from our other perl script
print "Foo is $foo\n";

还有很多东西要学,我建议你阅读documentation.

【讨论】:

    【解决方案2】:

    你想要IPC::System::Simplecapturex

    use IPC::System::Simple qw( capturex );
    my $output = capturex("perl", $path, $val1, $val2, @myarray);
    

    它甚至会为您处理错误。

    【讨论】:

    • 为什么是-1? OP 要求提供一个命令不受 shell 解释的反引号版本,而这正是 capturex 的含义。
    【解决方案3】:

    反引号就像在 shell 中直接调用一样工作:

    you@somewhere:~$ ./script.pl --key=value
    

    基本一样

    my $returnval = `./script.pl --key=value`;
    

    【讨论】:

    • --key=value 是什么意思?
    • 这只是一个传递参数的例子。将其替换为适用于您的脚本的任何内容;基本上$val1 $val2 ...
    【解决方案4】:

    对于同时调用其他传递参数和捕获输出的程序,我是IPC::Run 的忠实粉丝:

    use IPC::Run 'run';
    
    my $exitcode = run [ $command, @args ], ">", \my $output;
    
    # $exitcode contains the exit status and
    # $output contains the command's STDOUT data
    

    【讨论】:

    • 代替IPC::RunIPC::Cmd 提供了类似的功能并且是一个核心模块。
    【解决方案5】:

    这不是你想要的吗?

    my $returnval = `$path $val1 $val2 @myarray`;
    

    @Quentin 但是添加了这个有用的建议:如果您要传递的值是 foo "bar,那么在 shell 中您将不得不执行类似 "foo \"bar" 的操作。对 system 使用额外的参数将为您解决问题。使用反引号不会;你需要手动构造你想要的shell命令。

    【讨论】:

    • 它不会自动引用/转义参数
    • @Quentin:谢谢你的建议。我承认我不知道什么是自动报价。通过我的 Perl 联机帮助页快速 grep 出现三个,神秘的,传递对“自动引用”或“自动引用”的引用,但这些没有解释;网络搜索也不会立即发现任何非常有用的信息。如果你能抽出一点时间,你能再解释一下吗?谢谢。
    • 我试过了,然后我尝试了$path /$val1 /$val2 /@myarray,都没有工作:>
    • 如果您要传递的值是foo "bar,那么在shell 中您必须执行"foo \"bar" 之类的操作。对system 使用额外的参数将为您提供卡片。使用反引号不会,你需要手动构造你想要的shell命令。
    • $path \$val1 \$val2 \@myarray 用于调用带参数的函数。但返回的值似乎不合适。我是否必须将返回值写入退出函数,例如:exit(value1); ?
    猜你喜欢
    • 2011-03-23
    • 2010-10-22
    • 1970-01-01
    • 2013-10-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多