【问题标题】:How to let shell_exec act like if commands are running inside mac terminal?如果命令在 mac 终端内运行,如何让 shell_exec 表现得像?
【发布时间】:2014-06-19 01:35:56
【问题描述】:

当我在 php 脚本中运行命令时

echo shell_exec("which php");

我得到以下输出:

/usr/bin/php

但是在 mac 终端中运行相同的命令时

 which php

我得到以下输出

 php: aliased to /Applications/MAMP/bin/php/php5.5.10/bin/php

我的问题是如何让 shell_exec 像在 mac 终端中运行命令一样?

注意:我安装了 ZSH

【问题讨论】:

    标签: php linux macos shell zsh


    【解决方案1】:

    简答:

    这不起作用(可靠)。

    长答案:

    问题有三个:

    1. PHP 不使用您的登录 shell,但 /bin/sh
    2. 必须在使用它们的上下文中设置别名
    3. which 的输出取决于$PATH

    查看1.您可以通过回显$0来打印正在运行的shell的名称

    % echo $0
    zsh
    % php -r 'echo shell_exec("echo \$0");'
    sh
    

    如您所见,PHP 以 sh 开头,而不是 zsh。这意味着它还使用了 sh 的内置函数,或者如果没有内置函数则查找命令:

    % php -r 'echo shell_exec("which which");'
    /usr/bin/which
    % zsh -c 'which which'
    which: shell built-in command
    

    除非sh 链接到zsh,否则如果你想使用zsh 的内置命令,你必须使用zsh 运行命令:

    echo shell_exec("zsh -c 'which php'");
    

    这会启动/bin/sh,然后启动zsh,然后运行命令。

    虽然您可以使用sh 解决 PHP,但第二个问题更为严重:别名仅在定义它们的实例中设置。大多数情况下,这发生在某些配置文件中(例如~/.zshrc)。但是当以非交互方式使用zsh 时不会加载这些配置文件,也不会将别名传递给子进程:

    % grep foo ~/.zshrc
    alias foo=bar
    % which foo
    foo: aliased to bar
    % zsh -c 'which foo'
    foo not found
    % php -r 'echo shell_exec("zsh -c which\ foo");'
    foo not found
    

    总之,这意味着在 PHP 脚本中使用 which 是找出 php 的来源/位置的完全不可靠的方法。更重要的是,它的输出取决于$PATH,对于交互式和非交互式 shell,这也可能不同。

    【讨论】:

    • 您说“PHP 不使用您的登录 shell,而是使用 /bin/sh”。我发现其他 SO 答案也说明了这一点。但我找不到任何关于它的文档。 PHP 的源代码中唯一提到/bin/sh 的似乎是in proc_open.c。你有一些额外的信息/指针吗?
    • @CDuv 我希望,在 PHP 的源代码中只有一个函数主动调用 /bin/sh。任何其他需要它的函数都应该只调用这个函数,在本例中为proc_open。不幸的是,我对 PHP 或 C 的了解还不够,无法真正给你一个明确的答案。看起来shell_execproc_open 在某种程度上与in exec.h 相关联,但我无法按照代码说明是否、如何以及在何处调用shell_exec 会导致调用proc_open
    • 我得出了同样的结论,这是有道理的。谢谢:)
    【解决方案2】:

    你不能在 php 级别上做到这一点。

    您从调用中获得的输出是由执行您的请求的 shell 程序生成的。该外壳不在 php 中,而是在系统上控制的外壳,其行为也取决于系统。您不能期望本地 Linux 系统上的行为与某些 Mac 系统上的行为相同。

    如果您的问题是为什么在这两种情况下会生成不同的输出,那么答案是:因为安装了不同的 php 解释器。显然,shell 会将您指向运行它的系统上已安装和首选的那个。其他一切都没有意义。在第二个示例中,php 是指向该路径的 shell 内的别名,这一事实在您的本地 Linux 系统上没有任何值的信息。

    【讨论】:

      猜你喜欢
      • 2020-10-01
      • 1970-01-01
      • 1970-01-01
      • 2017-04-08
      • 1970-01-01
      • 2011-06-11
      • 1970-01-01
      • 2022-01-12
      • 2015-03-05
      相关资源
      最近更新 更多