Perl的反引号,系统和exec有什么区别?

时间:2009-04-28 21:47:54

标签: perl

有人可以帮帮我吗?在Perl中,有什么区别:

exec "command";

system("command");

print `command`;

还有其他方法来运行shell命令吗?

5 个答案:

答案 0 :(得分:254)

EXEC

执行命令,永不返回。   它就像函数中的return语句。

如果未找到命令,则exec返回false。   它永远不会返回true,因为如果发现命令它永远不会返回。   返回STDOUTSTDERR或退出命令状态也没有意义。   您可以在perlfunc中找到有关它的文档,   因为它是一种功能。

系统

执行命令,命令完成后继续运行Perl脚本。

返回值是命令的退出状态。   您可以在perlfunc

中找到相关文档

反引号

就像system执行一个命令一样,命令完成后你的perl脚本就会继续。

system 相反,返回值为命令的STDOUT。   qx//相当于反引号。   您可以在perlop中找到有关该文档的文档,因为与systemexec不同,它是一个运算符。


其他方式

以上缺少的是一种异步执行命令的方法。 这意味着您的perl脚本和命令同时运行。 这可以通过open来完成。 它允许您阅读STDOUT / STDERR并写入您的命令的STDIN。 但它依赖于平台。

还有几个模块可以简化这项任务。 有IPC::Open2IPC::Open3以及IPC::Run,以及 Win32::Process::Create如果你在Windows上。

答案 1 :(得分:163)

一般情况下,我会使用systemopenIPC::Open2IPC::Open3,具体取决于我想要做的事情。 qx//运算符虽然很简单,但其功能过于严格,在快速黑客之外非常有用。我发现open更加便捷。

system:运行命令并等待它返回

如果要运行命令,请使用system,不要关心它的输出,并且在命令完成之前不要让Perl脚本执行任何操作。

#doesn't spawn a shell, arguments are passed as they are
system("command", "arg1", "arg2", "arg3");

#spawns a shell, arguments are interpreted by the shell, use only if you
#want the shell to do globbing (e.g. *.txt) for you or you want to redirect
#output
system("command arg1 arg2 arg3");

qx// or ``:运行命令并捕获其STDOUT

当您想要运行命令时,请使用qx//,捕获它写入STDOUT的内容,并且在命令完成之前不要让Perl脚本执行任何操作。

#arguments are always processed by the shell

#in list context it returns the output as a list of lines
my @lines = qx/command arg1 arg2 arg3/;

#in scalar context it returns the output as one string
my $output = qx/command arg1 arg2 arg3/;

exec:用另一个进程替换当前进程。

当您想要运行命令时,请使用execfork,不要关心它的输出,也不要等待它返回。 system真的只是

sub my_system {
    die "could not fork\n" unless defined(my $pid = fork);
    return waitpid $pid, 0 if $pid; #parent waits for child
    exec @_; #replace child with new process
}

您可能还想阅读waitpidperlipc手册。

open:运行进程并为其STDIN或STDERR创建管道

如果要将数据写入进程的STDIN或从进程的STDOUT读取数据(但不能同时读取两者),请使用open

#read from a gzip file as if it were a normal file
open my $read_fh, "-|", "gzip", "-d", $filename
    or die "could not open $filename: $!";

#write to a gzip compressed file as if were a normal file
open my $write_fh, "|-", "gzip", $filename
    or die "could not open $filename: $!";

IPC::Open2:运行进程并为STDIN和STDOUT创建管道

当您需要读取和写入进程的STDIN和STDOUT时,请使用IPC::Open2

use IPC::Open2;

open2 my $out, my $in, "/usr/bin/bc"
    or die "could not run bc";

print $in "5+6\n";

my $answer = <$out>;

IPC::Open3:运行一个进程并创建一个到STDIN,STDOUT和STDERR的管道

当您需要捕获进程的所有三个标准文件句柄时,请使用IPC::Open3。我会写一个例子,但它的工作方式与IPC :: Open2大致相同,但与参数和第三个文件句柄的顺序略有不同。

答案 2 :(得分:17)

让我先引用手册:

perldoc exec()

  

exec函数执行系统命令,永不返回 - 如果要返回,则使用 system 而不是 exec

perldoc system()

  

与exec LIST完全相同,除了首先完成一个fork ,并且父进程等待子进程完成。

exec 系统相比,反引号不会为您提供返回值,而是收集STDOUT。

perldoc `String`

  

一个字符串,它(可能)被内插,然后作为系统命令用 / bin / sh 或其等价物执行。壳牌通配符,管道和重定向将受到尊重。返回收集的标准输出命令;标准错误不受影响。


备选方案:

在更复杂的场景中,您想要获取STDOUT,STDERR或返回码,您可以使用众所周知的标准模块,如IPC::Open2IPC::Open3

示例:

use IPC::Open2;
my $pid = open2(\*CHLD_OUT, \*CHLD_IN, 'some', 'cmd', 'and', 'args');
waitpid( $pid, 0 );
my $child_exit_status = $? >> 8;

最后,来自CPAN的IPC::Run也值得一看......

答案 3 :(得分:9)

Perl的反引号(`),systemexec之间有什么区别?

exec -> exec "command"; ,
system -> system("command"); and 
backticks -> print `command`;

exec

exec执行命令,永远不会恢复Perl脚本。像return语句这样的脚本就是函数。

如果未找到该命令,exec将返回false。它永远不会返回true,因为如果找到命令,它永远不会返回。返回STDOUTSTDERR或退出命令状态也没有意义。您可以在 perlfunc 中找到有关它的文档,因为它是一个函数。

例如:

#!/usr/bin/perl
print "Need to start exec command";
my $data2 = exec('ls');
print "Now END exec command";
print "Hello $data2\n\n";

在上面的代码中,有三个print语句,但由于exec离开了脚本,因此只执行第一个print语句。此外,exec命令输出未分配给任何变量。

在这里,只有你只得到第一个print语句的输出和在标准输出上执行ls命令。

system

system执行命令,并在命令完成后恢复Perl脚本。返回值是命令的退出状态。您可以在 perlfunc 中找到有关它的文档。

例如:

#!/usr/bin/perl
print "Need to start system command";
my $data2 = system('ls');
print "Now END system command";
print "Hello $data2\n\n";

在上面的代码中,有三个print语句。在system命令之后恢复脚本时,将执行所有三个打印语句。

此外,运行system 的结果已分配给data2,但指定的值为0ls的退出代码)。

在这里,您将获得第一个print语句的输出,然后是ls命令的输出,然后是标准输出的最后两个print语句的输出。

反引号(`

system一样,在反引号中包含一个命令会执行该命令,并在命令完成后恢复您的Perl脚本。与system相反,返回值为命令的STDOUTqx//相当于反引号。您可以在 perlop 中找到有关它的文档,因为与系统和exec不同,它是一个运算符。

例如:

#!/usr/bin/perl
print "Need to start backticks command";
my $data2 = `ls`;
print "Now END system command";
print "Hello $data2\n\n";

在上面的代码中,有三个print语句,正在执行这三个语句。 ls的输出不会直接标准化,而是分配给变量data2,然后由最终的print语句打印。

答案 4 :(得分:2)

'exec'和'system'之间的区别在于exec用'command'替换你当前的程序,并且NEVER返回你的程序。另一方面,系统分叉并运行“命令”,并在运行完成后返回“命令”的退出状态。后面的勾选运行'命令',然后返回一个表示其标准输出的字符串(无论它打印到屏幕上)

您也可以使用popen来运行shell命令,我认为有一个shell模块 - “使用shell”,可以透明地访问典型的shell命令。

希望能为你澄清一下。