【问题标题】:Executing shell script within PHP在 PHP 中执行 shell 脚本
【发布时间】:2025-11-14 19:00:01
【问题描述】:

当我们安装一个程序(例如 DBMS)时,它可以通过 shell 命令本地运行;但是为了在 PHP、Perl、Python 等中运行它,我们需要适当的 API/驱动程序。这可能会减慢进程并带来新的限制(例如,CBD 不需要适合内存,但需要在 Perl 中与 CDB_File 一起使用)。

问题 1: shell 是否是运行程序最快和最好的地方(无论我们的应用程序和目的如何)。

在 PHP 中使用 exec() 或 shell_exec() 执行 ssh 命令是很常见的。但这种情况很少见。

问题 2: 定期将 php 代码与 shell 命令混合使用是否方便?创建一个长的 shell 脚本,然后通过 exec("./shell.sh") 在 php 中运行它。此类 Web 脚本是否存在任何安全问题或有问题的考虑?

问题 3: PHP(和其他脚本语言)本身运行一个 shell 命令来执行一个过程(例如读取文件或连接到数据库)。正确的?所以shell命令是通过php还是直接命令不可避免?

【问题讨论】:

    标签: php linux shell command-line


    【解决方案1】:

    除了hakre的cmets....

    在 PHP 中使用 exec() 或 shell_exec() 执行 ssh 命令是很常见的。但这种情况很少见。

    抛开两句话中明显的矛盾修饰,通过 exec/shell_exec 调用 ssh 是一个非常愚蠢的想法。作为一个快速破解,您知道密钥对身份验证已经到位,那么它将解决问题 - 但对于更一般的应用程序,您应该使用 proc_open 以便在相关流上使用正确的握手 - 或ssh2 extension

    关于第三季度,没有。在 PHP 提供函数的地方,几乎不可避免地它将被当前进程/线程作为本机函数调用来实现(我知道的唯一例外是 POSIX 系统上的 mail() 命令)。必须使用 exec、shell_exec、passthru、popen... 等创建一个新进程。

    关于安全性....由于网络服务器(以及它的脚本)运行单个 uid,除了用户权限和 ulimit(例如 base_opendir)之外,通常还会对访问施加额外的限制 - 但这些不适用于单独的进程。因此,当您开始一个新流程时,您会将上下文跨入不同的安全模型。

    【讨论】:

    • 感谢您的描述性回答。你的意思是在创建文件的时候,php直接和linux内核通信?
    • 是的。只有内核才能真正在文件系统上创建/读取/写入文件——并且没有额外的进程来调解从 PHP 到操作系统的调用。
    【解决方案2】:

    问题 1: shell 是否是运行程序最快和最好的地方(无论我们的应用程序和目的如何)。

    这取决于该程序的命令行界面是否是与该程序交互的最快方式,以及该程序的 CLI 界面是否是运行该程序的最佳方式。所以这取决于程序。例如。您可以通过 shell 执行 Firefox 网络浏览器,但这不是使用它的最佳位置。

    问题 2: 定期将 php 代码与 shell 命令混合使用是否方便 [原文如此!]?创建一个长的 shell 脚本,然后通过 exec("./shell.sh") 在 php 中运行它。此类 Web 脚本是否存在任何安全问题或有问题的考虑?

    在定期使用 shell 命令时,什么方便或不方便取决于用户的看法。当然,因为在计算机上运行的所有内容都具有安全隐患,所以对于 shell 脚本也是如此。

    【讨论】:

    • 1.我的意思是当我们运行 firefox 时,它将通过 shell 执行到 OS kerl。因此,这是我们运行 Firefox 所需的一半。 2.我的意思是在php中有很多shell命令可以吗?
    • @Ali:为什么不呢?在我看来,您应该始终使用最适合特定工作的工具。当它是一个 shell 脚本时,只需使用 shell 脚本——即使它是通过 PHP 执行的。但是:确保清理传递给 shell 脚本的任何(动态)参数(例如,使用 escapeshellarg
    • 这取决于。没关系,只要注意你清楚如果你混合流程你会做什么。事实上,在网络服务器的历史上,实际执行 shell 脚本,这就是 CGI 接口的诞生方式。您也可以使用 PHP 执行 shell 脚本,只需将该语言用作工具。 PHP 通常是粘合剂,将其他组件组合到服务器 HTTP 响应中。如果一个程序有一个 PHP API,它通常更灵活,但肯定每个抽象/封装都有代价。 Shell 脚本通常更直接,但最终可能更难维护。这取决于您定义接口。
    • @hakre:你给了我一个非常宝贵的提示!
    • @harald:您引用了一个重要问题,因为我们需要考虑 INSERT 到 SQL 数据库中