如果命令在Mac终端中运行,如何让shell_exec起作用?

问题描述:

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

When I am running command inside a php script

echo shell_exec("which php");

我得到以下输出:

/usr/bin/php


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


However when running the same command inside mac terminal

 which php

我得到以下输出

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


我的问题是,如果命令在Mac终端中运行,如何让shell_exec起作用?


my question is how to let shell_exec act like if commands are running inside mac terminal?

注意:我已经安装了ZSH

note: that i have ZSH installed

简短答案:

这是行不通的(可靠地).

This will not work (reliably).

长答案:

问题有三重:

  1. PHP不使用您的登录Shell,但使用/bin/sh
  2. 别名必须在使用上下文中设置
  3. which的输出取决于$PATH
  1. PHP does not use your login shell but /bin/sh
  2. Aliases have to be set in the context they are used
  3. The output of which depends on $PATH

要查看 1.您可以通过回显$0

To see 1. You can print the name of the running shell by echoing $0

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

如您所见,PHP启动sh而不是zsh.这意味着它还使用sh的内置函数,或者在没有内置函数的情况下查找命令:

As you can see, PHP starts sh instead of zsh. That meens it also uses the builtins of sh or looks for a command if there is no builtin:

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

除非sh链接到zsh,除非您想使用zsh的内置函数,否则必须使用zsh运行命令:

Unless sh links to zsh, that meens, if you want to make use of zsh's builtins you have to run your command with zsh:

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

这将启动/bin/sh,然后反过来启动zsh,然后运行命令.

This starts /bin/sh, which in turn starts zsh, which then runs the command.

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

While you can work around PHP using sh, the second problem is more grave: Aliases are only set within the instance in which they are defined. Most of the time this happens in some configuration file (e.g. ~/.zshrc). But these configuration files are not loaded when using zsh non-interactively and neither are aliases passed to child processes:

% 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来说,它也可能有所不同.

In conclusion that means, that using which from inside a PHP script is an entirely unreliable way to find out the origin/location of php. Even more so as the output of which depends on $PATH, which may also be different for interactive and non-interactive shells.