【问题标题】:What's behind the 'system' function in Perl?Perl 中的“系统”函数背后是什么?
【发布时间】:2011-02-11 20:36:07
【问题描述】:

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

rmdir foo

system('rmdir foo');

【问题讨论】:

  • 尽量不要不必要地调用系统命令,除非它的专有和 Perl 还没有模块/API。要删除目录,请使用 Perl 自己的 rmdir()。操作系统的大部分系统命令都可以在 Perl 本身中完成
  • 您可以在perldoc.perl.org 阅读文档。系统条目回答了这个问题。对您不理解的文档提出问题很好,但至少先尝试一下 :)
  • 此外,您可以在上周发给 The Effective Perler 的帖子中阅读有关不同类型 Perl 交互的更多信息:effectiveperlprogramming.com/blog/150

标签: perl


【解决方案1】:
  1. 两者之间的区别在于,第二个将打开(fork)一个子进程(将是 rmdir 命令),而第一个将使用 API 直接进行 Unix 系统调用而不打开进程.打开子进程是昂贵的资源明智的。

  2. system() 调用将始终打开一个要执行的子进程,但是,它可能会打开一个 shell,该 shell 将反过来将所需的程序作为其自己的子进程分叉(从而导致 2 个子进程),或者分叉程序直接作为子进程。

    perldoc -f system 中详细说明了 Perl 在 system() 调用期间何时打开 shell 的选择。简短(并非 100% 准确)的版本是:

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

    • 如果只有一个参数并且计算结果为没有元字符;或者有 >1 个元素的参数列表,程序直接绕过 shell 分叉。

因此:

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 ">" 

【讨论】:

  • 对于这种系统调用'system("rmdir foo > out.txt");'使用 Shell 脚本会更好!没有?
  • @JohnJohnGa - 如果这是程序中唯一的一行,是的。如果这是 50 行 Perl 代码中的 1 行,这需要 500 行等效的 shell 脚本,不。如果这是 Web 应用程序的 1 行,而您决定用 shell 脚本编写 Web 应用程序,我很同情您和您的雇主 :)
【解决方案2】:

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

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

*system 如果您的命令包含管道、输入/输出重定向、&& 等,将创建一个额外的sh 进程。这不适用于您的情况,但会使system 选项更慢。

【讨论】:

    猜你喜欢
    • 2015-05-24
    • 2011-03-01
    • 1970-01-01
    • 2012-10-02
    • 2020-09-08
    • 1970-01-01
    • 1970-01-01
    • 2022-08-14
    • 1970-01-01
    相关资源
    最近更新 更多