如何让shell_exec像命令在 mac 终端内运行一样运行


How to let shell_exec act like if commands are running inside mac terminal?

当我在 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

简短回答:

这将不起作用(可靠地(。

长答案:

问题有三个方面:

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

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

% 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 程序生成。该 shell 不在 php 中,而是在系统上控制的 shell,其行为也依赖于系统。您不能期望在本地 Linux 系统上出现与从某些 Mac 系统获得的行为相同的行为。

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