如果命令在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).
长答案:
问题有三重:
- PHP不使用您的登录Shell,但使用
/bin/sh
- 别名必须在使用上下文中设置
-
which
的输出取决于$PATH
- PHP does not use your login shell but
/bin/sh
- Aliases have to be set in the context they are used
- 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.