#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");
#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/;
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
}
#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: $!";
6条答案
按热度按时间zi8p0yeb1#
exec
执行一个命令并且 * 从不返回 *。这就像函数中的
return
语句。如果没有找到命令,
exec
返回false。它永远不会返回true,因为如果找到命令,它永远不会返回。返回STDOUT
,STDERR
或命令的退出状态也没有意义。你可以在perlfunc
中找到有关它的文档,因为它是一个函数。系统
执行一个命令,并且在命令完成后继续执行Perl脚本。
返回值是命令的退出状态。您可以在
perlfunc
中找到有关它的文档。反引号
像
system
执行一个命令,你的perl脚本在命令完成后继续。与**
system
相反,返回值是命令的STDOUT
。qx//
相当于反引号。您可以在perlop
**中找到有关它的文档,因为与system
和exec
不同,它是一个运算符。其他方式
上面缺少的是一种异步执行命令的方法。这意味着您的perl脚本和命令同时运行。这可以通过
open
来完成。它允许您读取STDOUT
/STDERR
并写入命令的STDIN
。尽管它依赖于平台。还有几个模块可以简化这个任务。有
IPC::Open2
和IPC::Open3
和IPC::Run
,以及Win32::Process::Create
,如果你是在windows上。vjrehmav2#
一般来说,我使用
system
,open
,IPC::Open2
或IPC::Open3
,这取决于我想做什么。qx//
运算符,虽然简单,但在其功能上过于限制,在快速黑客之外非常有用。我发现open
更方便。system
:运行命令并等待返回当您想运行一个命令,不关心它的输出,并且不希望Perl脚本在命令完成之前做任何事情时,可以使用
system
。字符串
或
型
qx//
或``:运行命令并捕获其STDOUT当您想要运行一个命令,捕获它写入STDOUT的内容,并且不希望Perl脚本在命令完成之前执行任何操作时,可以使用
qx//
。型
exec
:将当前进程替换为其他进程。当你想运行一个命令,不关心它的输出,也不想等待它返回时,沿着使用
exec
和fork
。型
您可能还想阅读
waitpid
和perlipc
手册。open
:运行一个进程并创建一个到其STDIN或STDERR的管道当您想将数据写入进程的STDIN或从进程的STDOUT读取数据时(但不能同时进行),请使用
open
。型
IPC::Open2:运行一个进程并创建一个到STDIN和STDOUT的管道
当您需要读取和写入进程的STDIN和STDOUT时,请使用
IPC::Open2
。型
IPC::Open3:运行一个进程并创建一个到STDIN、STDOUT和STDERR的管道
当你需要捕获进程的所有三个标准文件句柄时,使用
IPC::Open3
。我会写一个例子,但它的工作方式与IPC::Open2基本相同,只是参数和第三个文件句柄的顺序略有不同。rkue9o1l3#
我先引用一下手册:
perldoc exec():
exec函数执行一个系统命令,并且从不返回--如果您希望它返回,请使用 system 而不是 exec
perldoc system():
执行与exec LIST完全相同的操作,不同之处在于首先完成一个fork,父进程等待子进程完成。
与 exec 和 system 不同,反引号不给予返回值,而是返回收集的STDOUT。
perldoc
String
:一个字符串,它(可能)被插值,然后作为系统命令使用 /bin/sh 或其等效命令执行。Shell通配符、管道和重定向将被接受。收集的命令的标准输出将被返回;标准错误不受影响。
备选:
在更复杂的情况下,如果你想获取STDOUT,STDERR或返回代码,你可以使用众所周知的标准模块,如IPC::Open2和IPC::Open3。
范例:
字符串
最后,来自CPAN的IPC::Run也值得一看。
uoifb46i4#
Perl的反引号(```),
system
和exec
之间有什么区别?字符串
exec
exec
执行一个命令并且从不恢复Perl脚本。它对于脚本就像return
语句对于函数一样。如果找不到命令,
exec
返回false。它永远不会返回true,因为如果找到命令,它永远不会返回。返回STDOUT
,STDERR
或命令的退出状态也没有意义。您可以在perlfunc中找到有关它的文档,因为它是一个函数。例如:
型
在上面的代码中,有三个
print
语句,但由于exec
离开脚本,只有第一个print语句被执行。此外,exec
命令输出没有被分配给任何变量。在这里,您只得到第一个
print
语句的输出和在标准输出上执行ls
命令的输出。system
system
执行一个命令,当命令执行完毕后,您的Perl脚本会继续执行。返回值是命令的退出状态。您可以在perlfunc中找到相关文档。例如:
型
在上面的代码中,有三个
print
语句。当脚本在system
命令之后恢复时,所有三个print语句都被执行。此外,运行
system
* 的结果 * 被分配给data2
,但分配的值是0
(ls
的退出代码)。在这里,您将获得第一个
print
语句的输出,然后是ls
命令的输出,最后两个print
语句在标准输出上的输出。反引号(```)
像
system
一样,将命令包含在反引号中会执行该命令,并且在命令完成后会继续执行Perl脚本。与system
相反,返回值是命令的STDOUT
。qx//
等效于反引号。您可以在perlop中找到有关它的文档,因为与system和exec
不同,它是一个运算符。例如:
型
在上面的代码中,有三个
print
语句,并且这三个语句都被执行。ls
的输出不会直接输出到标准输出,而是分配给变量data2
,然后由最后的print语句打印。gzszwxb45#
“exec”和“system”之间的区别是exec会用“command”替换当前程序,而NEVER会返回到程序。另一方面,system会分叉并运行“command”,并在“command”运行完毕后返回“command”的退出状态。反勾号运行“command”,然后返回一个代表其标准输出的字符串(无论它会打印到屏幕上)。
你也可以使用popen来运行shell命令,我认为有一个shell模块- 'use shell',它可以让你透明地访问典型的shell命令。
希望这能为你澄清。
km0tfn4u6#
总的来说,
*exec执行,永远不会回来。
*system执行并返回退出代码。
*backticks执行并返回执行结果。