从 Perl 或 PHP 脚本执行终端命令是一种好习惯吗?

Is it a good practice to execute terminal commands from a Perl or PHP script?

就像使用反引号或 exec()system() 执行命令一样。

为什么不呢?

但是,请小心并转义命令中插入的所有字符串:

  • 在PHP中:escapeshellarg()
  • 在 Perl 中:Perl equivalent of PHP's escapeshellarg

某些操作系统命令可能具有语言中不可用的内置功能(Perl 的 mkdir() 缺少 *ix mkdir 的 -p)。再一次,使用语言构造而不是解析输出可能更容易做一些事情(readdir()与ls)。

并且重要的是要记住,用 Perl 编写的东西可能比调用 OS 特定的外部程序更适合非 Unix 系统。

这是很好的*练习。 Perl 和 PHP 在很多方面都很棒,但它们并不是在所有方面都很棒,并且在您的项目中有一个使用外部程序和其他工具的用例。但是 Perl 绝对擅长的一件事就是将输入和输出格式粘合在一起,让您将几个不同的工具混搭到一个项目中,让项目的每个部分都做他们最擅长的事情。

* 我的意思是,这通常是一个很好的练习。 @files=qx(ls $dir)@txt=qx(cat $textfile) 之类的东西让所有思维正常的 Perl 程序员都畏缩不前。

是的,这在几乎所有情况下都是不好的做法!如果您有选择,尤其如此。

执行外部命令是:

  • 非常很难正确地做(但很容易得到某种工作)。您不能只转义 shell args 并收工,您必须考虑可能存在的多级转义以用于可能不同的语言。

  • 。 fork+exec 到例如rm 很容易比相应的系统调用慢一千倍。

  • 一个死板、容易出错且缺乏表达力的整合点。您通常必须将数据转换为简单的字符串列表并返回。您不能使用该语言的功能,如异常处理、嵌套数据结构或回调。

因此,以下是调用外部命令的错误原因

  • 不知道如何用您的语言执行 X,但知道 shell 命令。一个典型的例子是cp -R foo bar

  • 不知道某些东西是如何工作的,但知道 shell oneliner 可以做到这一点。一个典型的例子是foo *.mp4 > >(tee file)

  • 不想学习新的 API 例如json 或 http,而是使用 shell 工具,例如 jqcurl.

但是,如果您正在调用一个执行重要任务的程序,该程序没有本机库或绑定,并且您知道如何使用 execve 语义调用(不是 system 或调用 shells 的 perl exec 语义),这是一个有价值的工具。

执行上述所有外部命令的良好用法示例是调用 make 从安装程序构建项目,或 运行 java -jar ... 启动 Minecraft 服务器。