有人能帮帮我吗?在Perl中,以下两者的区别是什么:
exec "command";
and
system("command");
and
print `command`;
还有其他方法来运行shell命令吗?
有人能帮帮我吗?在Perl中,以下两者的区别是什么:
exec "command";
and
system("command");
and
print `command`;
还有其他方法来运行shell命令吗?
当前回答
Perl的反撇号(')、system和exec之间有什么区别?
exec -> exec "command"; ,
system -> system("command"); and
backticks -> print `command`;
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";
在上面的代码中,有三个print语句,但是由于exec离开脚本,只执行了第一个print语句。此外,exec命令的输出没有被分配给任何变量。
在这里,您只得到第一个打印语句的输出和在标准输出上执行ls命令的输出。
系统
系统执行一个命令,并且在命令执行完毕后恢复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";
在上面的代码中,有三个打印语句。当脚本在执行system命令后恢复时,将执行所有三个print语句。
同样,运行system的结果被赋值给data2,但赋值为0 (ls的退出代码)。
在这里,您将获得第一个打印语句的输出,然后是ls命令的输出,然后是标准输出中最后两个打印语句的输出。
backticks(’)
与系统类似,用反引号括起命令将执行该命令,并且在命令执行完毕后恢复Perl脚本。与system相反,返回值是命令的STDOUT。Qx //等价于反撇号。您可以在perlop中找到关于它的文档,因为与system和exec不同,它是一个操作符。
例如:
#!/usr/bin/perl
print "Need to start backticks command";
my $data2 = `ls`;
print "Now END system command";
print "Hello $data2\n\n";
在上面的代码中,有三个打印语句,这三个语句都被执行了。ls的输出不会直接输出,而是赋值给变量data2,然后由最后的print语句输出。
其他回答
Perl的反撇号(')、system和exec之间有什么区别?
exec -> exec "command"; ,
system -> system("command"); and
backticks -> print `command`;
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";
在上面的代码中,有三个print语句,但是由于exec离开脚本,只执行了第一个print语句。此外,exec命令的输出没有被分配给任何变量。
在这里,您只得到第一个打印语句的输出和在标准输出上执行ls命令的输出。
系统
系统执行一个命令,并且在命令执行完毕后恢复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";
在上面的代码中,有三个打印语句。当脚本在执行system命令后恢复时,将执行所有三个print语句。
同样,运行system的结果被赋值给data2,但赋值为0 (ls的退出代码)。
在这里,您将获得第一个打印语句的输出,然后是ls命令的输出,然后是标准输出中最后两个打印语句的输出。
backticks(’)
与系统类似,用反引号括起命令将执行该命令,并且在命令执行完毕后恢复Perl脚本。与system相反,返回值是命令的STDOUT。Qx //等价于反撇号。您可以在perlop中找到关于它的文档,因为与system和exec不同,它是一个操作符。
例如:
#!/usr/bin/perl
print "Need to start backticks command";
my $data2 = `ls`;
print "Now END system command";
print "Hello $data2\n\n";
在上面的代码中,有三个打印语句,这三个语句都被执行了。ls的输出不会直接输出,而是赋值给变量data2,然后由最后的print语句输出。
一般来说,我使用system、open、IPC::Open2或IPC::Open3,这取决于我想做什么。qx//操作符虽然简单,但在功能上限制太大,在快速攻击之外非常有用。我发现开放更方便。
系统:执行命令并等待返回
当您希望运行命令时,请使用system,不要关心它的输出,并且在命令执行完毕之前不希望Perl脚本执行任何操作。
#doesn't spawn a shell, arguments are passed as they are
system("command", "arg1", "arg2", "arg3");
or
#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//或' ':运行一个命令并捕获它的STDOUT
当您希望运行一个命令,捕获它写入STDOUT的内容,并且在命令执行完毕之前不希望Perl脚本执行任何操作时,可以使用qx//。
#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:将当前进程替换为其他进程。
当你想运行一个命令,不关心它的输出,也不想等待它的返回时,使用exec和fork。系统实际上只是
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
}
您可能还需要阅读waitpid和perlipc手册。
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基本相同,只是参数的顺序略有不同,还有第三个文件句柄。
“exec”和“system”的区别在于,exec用“command”替换你当前的程序,并且永远不会返回到你的程序。另一方面,System会fork并运行'command',并在运行完成时返回'command'的退出状态。后勾号运行'command',然后返回一个表示其标准输出的字符串(无论它要打印到屏幕上的是什么)。
你也可以使用popen来运行shell命令,我认为有一个shell模块- 'use shell',它可以让你透明地访问典型的shell命令。
希望这能为你们解释清楚。
让我先引用一下手册:
Perldoc exec():
exec函数执行一个系统命令并且永不返回——如果你想让它返回,请使用system而不是exec
perldoc几千个():
做和exec LIST完全一样的事情,除了先做一个fork,并且父进程等待子进程完成。
与exec和system相反,反勾号不会给你返回值,而是给你收集的STDOUT。
perldoc‘String’:
(可能)插入的字符串,然后作为系统命令使用/bin/sh或等效命令执行。Shell通配符、管道和重定向将得到尊重。返回收集到的命令的标准输出;标准错误不受影响。
选择:
在更复杂的情况下,你想获取STDOUT, STDERR或返回码,你可以使用众所周知的标准模块,如IPC::Open2和IPC::Open3。
例子:
use IPC::Open2;
my $pid = open2(\*CHLD_OUT, \*CHLD_IN, 'some', 'cmd', 'and', 'args');
waitpid( $pid, 0 );
my $child_exit_status = $? >> 8;
最后,IPC::Run from CPAN也值得一看…
exec
执行一个命令并且永不返回。 它就像函数中的return语句。
如果未找到命令,则exec返回false。 它永远不会返回true,因为如果找到了命令,它就永远不会返回。 返回命令的STDOUT、STDERR或退出状态也没有意义。 你可以在perlfunc中找到关于它的文档, 因为它是一个函数。
系统
执行命令,并在命令完成后继续执行Perl脚本。
返回值为命令的退出状态。 您可以在perlfunc中找到有关它的文档。
backticks
比如系统执行一个命令,你的perl脚本在命令完成后继续执行。
与系统相反,返回值是命令的STDOUT。 Qx //等价于反撇号。 您可以在perlop中找到有关它的文档,因为与system和execit不同,它是一个操作符。
其他的方式
上面所缺少的是异步执行命令的方法。 这意味着perl脚本和命令同时运行。 这可以通过开放来实现。 它允许您读取STDOUT/STDERR并写入命令的STDIN。 但它依赖于平台。
还有几个模块可以简化这个任务。 有IPC::Open2和IPC::Open3和IPC::Run,以及 Win32::Process::如果你在windows上创建。