Perl中“系统”功能的背后是什么?

时间:2010-04-24 11:53:02

标签: perl

我可以认为它将打开一个shell,执行参数(shell命令)并以标量返回结果。 但是,在Perl脚本中执行system函数比shell命令更快。 它会在C中调用此命令吗? 如果是,那么

之间有什么区别
rmdir foo

system('rmdir foo');

2 个答案:

答案 0 :(得分:11)

  1. 两者之间的区别在于第二个将打开(fork)一个子进程(它将是rmdir命令),而第一个将使用API​​进行直接Unix系统调用而无需打开进程。打开子进程昂贵资源明智。

  2. system()调用将始终打开一个子进程来执行,但是,它可以打开一个shell,然后将所需的程序作为自己的子进程分叉(从而产生2个子进程) ),或直接将程序作为子进程分叉。

    system()调用期间,Perl将在system("rmdir foo"); # forks off rmdir command directly system("rmdir", "foo"); # forks off rmdir command directly system("rmdir foo > out.txt"); # forks off a shell because of ">" 调用期间打开shell的选择将在perldoc -f system中详细说明。简短(而非100%准确)的版本是:

    • 如果系统调用只有一个参数,并且参数的计算结果为包含shell元字符的字符串,则首先将分叉一个shell。

    • 如果只有一个参数,则评估为无元字符;或者有一个> 1元素的参数列表,程序直接绕过shell分叉。

  3. 因此:

    {{1}}

答案 1 :(得分:5)

您的system调用启动一个单独的进程,而Perl自己的rmdir将在Perl进程的上下文中调用本机C函数。两种方法最终都会进行相同的系统调用,但打开一个新进程的效率会降低。*

最佳实践是使用Perl自己的函数(例如rmdir):它们是可移植的,您不必担心解释shell退出代码,转义文件名中的元字符以防止安全风险等。

如果您的命令包含管道,输入/输出重定向,system等,

* sh将创建一个额外的&&进程。这不适用于您的情况,但可以使{ {1}}选项更慢。