Perl的backticks、system和exec有什么区别?

4smxwvx5  于 2023-11-22  发布在  Perl
关注(0)|答案(6)|浏览(268)

有没有人可以帮助我?在Perl中,以下两者之间的区别是什么:

exec "command";

字符串

system("command");


print `command`;


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

zi8p0yeb

zi8p0yeb1#

exec

执行一个命令并且 * 从不返回 *。这就像函数中的return语句。
如果没有找到命令,exec返回false。它永远不会返回true,因为如果找到命令,它永远不会返回。返回STDOUTSTDERR或命令的退出状态也没有意义。你可以在perlfunc中找到有关它的文档,因为它是一个函数。

系统

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

反引号

system执行一个命令,你的perl脚本在命令完成后继续。
与**system相反,返回值是命令的STDOUTqx//相当于反引号。您可以在perlop**中找到有关它的文档,因为与systemexec不同,它是一个运算符。

其他方式

上面缺少的是一种异步执行命令的方法。这意味着您的perl脚本和命令同时运行。这可以通过open来完成。它允许您读取STDOUT/STDERR并写入命令的STDIN。尽管它依赖于平台。
还有几个模块可以简化这个任务。有IPC::Open2IPC::Open3IPC::Run,以及Win32::Process::Create,如果你是在windows上。

vjrehmav

vjrehmav2#

一般来说,我使用systemopenIPC::Open2IPC::Open3,这取决于我想做什么。qx//运算符,虽然简单,但在其功能上过于限制,在快速黑客之外非常有用。我发现open更方便。

system:运行命令并等待返回

当您想运行一个命令,不关心它的输出,并且不希望Perl脚本在命令完成之前做任何事情时,可以使用system

#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//或``:运行命令并捕获其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:将当前进程替换为其他进程。

当你想运行一个命令,不关心它的输出,也不想等待它返回时,沿着使用execfork

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基本相同,只是参数和第三个文件句柄的顺序略有不同。

rkue9o1l

rkue9o1l3#

我先引用一下手册:

perldoc exec()
exec函数执行一个系统命令,并且从不返回--如果您希望它返回,请使用 system 而不是 exec
perldoc system()
执行与exec LIST完全相同的操作,不同之处在于首先完成一个fork,父进程等待子进程完成。
execsystem 不同,反引号不给予返回值,而是返回收集的STDOUT。
perldoc String
一个字符串,它(可能)被插值,然后作为系统命令使用 /bin/sh 或其等效命令执行。Shell通配符、管道和重定向将被接受。收集的命令的标准输出将被返回;标准错误不受影响。

备选:

在更复杂的情况下,如果你想获取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也值得一看。

uoifb46i

uoifb46i4#

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命令之后恢复时,所有三个print语句都被执行。
此外,运行system * 的结果 * 被分配给data2,但分配的值是0ls的退出代码)。
在这里,您将获得第一个print语句的输出,然后是ls命令的输出,最后两个print语句在标准输出上的输出。

反引号(```)

system一样,将命令包含在反引号中会执行该命令,并且在命令完成后会继续执行Perl脚本。与system相反,返回值是命令的STDOUTqx//等效于反引号。您可以在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";


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

gzszwxb4

gzszwxb45#

“exec”和“system”之间的区别是exec会用“command”替换当前程序,而NEVER会返回到程序。另一方面,system会分叉并运行“command”,并在“command”运行完毕后返回“command”的退出状态。反勾号运行“command”,然后返回一个代表其标准输出的字符串(无论它会打印到屏幕上)。
你也可以使用popen来运行shell命令,我认为有一个shell模块- 'use shell',它可以让你透明地访问典型的shell命令。
希望这能为你澄清。

km0tfn4u

km0tfn4u6#

总的来说,

*exec执行,永远不会回来。
*system执行并返回退出代码。
*backticks执行并返回执行结果。

相关问题