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

rlb*_*ond 231 perl

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

exec "command";
Run Code Online (Sandbox Code Playgroud)

system("command");
Run Code Online (Sandbox Code Playgroud)

print `command`;
Run Code Online (Sandbox Code Playgroud)

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

Lud*_*erl 259

EXEC

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

如果未找到该命令,则exec返回false.它永远不会返回true,因为如果发现命令它永远不会返回.也有在没有返回点STDOUT,STDERR或命令的退出状态.您可以在其中找到有关它的文档 perlfunc,因为它是一个函数.

系统

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

返回值是命令的退出状态.您可以在中找到有关它的文档 perlfunc.

反引号

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

system返回值相反的是STDOUT命令. qx//相当于反叛.你可以找到它的文档perlop,因为不像system并且exec它是操作员.


其他方法

上面缺少的是一种异步执行命令的方法.这意味着您的perl脚本和命令同时运行.这可以通过以下方式实现open.它允许您读取STDOUT/ STDERR写入STDIN命令.它依赖于平台.

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

  • perlcunc,也许这将是我的新昵称;-) (7认同)
  • 为了记录,反引号和qx []也填充$?(OS返回值). (7认同)

Cha*_*ens 165

总的来说,我使用system,open,IPC::Open2,或IPC::Open3取决于我想做的事情.该qx//操作虽然简单,太在其功能限制要快黑客之外是非常有用的.我发现open更方便.

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

使用system时要运行的命令,不关心它的输出,并且不希望Perl脚本做任何事情,直到命令完成.

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

要么

#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");
Run Code Online (Sandbox Code Playgroud)

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

使用qx//时要运行一个命令,捕捉它写到标准输出,并且不希望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/;
Run Code Online (Sandbox Code Playgroud)

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

使用exec连同fork当你想运行一个命令,不关心它的输出,并且不希望等待它返回. 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
}
Run Code Online (Sandbox Code Playgroud)

您可能还想阅读waitpidperlipc手册.

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

使用open时要将数据写入过程的STDIN或从一个进程的标准输出读取数据(但不能同时在同一时间).

#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: $!";
Run Code Online (Sandbox Code Playgroud)

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

使用IPC::Open2时需要读取和写入过程的STDIN和STDOUT.

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>;
Run Code Online (Sandbox Code Playgroud)

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

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


Ben*_*gel 17

让我先引用手册:

perldoc exec():

exec函数执行系统命令并且永远不会返回 - 如果要返回,请使用system而不是exec

perldoc系统():

与exec LIST完全相同,除了先完成fork,父进程等待子进程完成.

execsystem相比,反引号不会给你返回值,而是收集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;
Run Code Online (Sandbox Code Playgroud)

最后,IPC ::从CPAN 运行也值得一看......

  • 这是一个粗鲁的回应.你应该尽量在没有愤怒的情况下提供帮助. (3认同)
  • 我认为他只是参考了 ol' RTFM :P (2认同)
  • 我当然没有把它解释为粗鲁.也许是布鲁斯克,但这不是一个非常聪明的问题,需要一个深思熟虑的答案. (2认同)

小智 11

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

exec -> exec "command"; ,
system -> system("command"); and 
backticks -> print `command`;
Run Code Online (Sandbox Code Playgroud)

exec

exec执行命令,永远不会恢复Perl脚本.对于像return语句这样的脚本是一个函数.

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

例如:

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

在上面的代码中,有三个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";
Run Code Online (Sandbox Code Playgroud)

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

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

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

反叛(`)

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

例如:

#!/usr/bin/perl
print "Need to start backticks command";
my $data2 = `ls`;
print "Now END system command";
print "Hello $data2\n\n";
Run Code Online (Sandbox Code Playgroud)

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