How to let shell_exec act like if commands are run

2019-07-09 01:42发布

When I am running command inside a php script

echo shell_exec("which php");

I am getting the following output:

/usr/bin/php

However when running the same command inside mac terminal

 which php

i am getting the following output

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

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

note: that i have ZSH installed

2条回答
爱情/是我丢掉的垃圾
2楼-- · 2019-07-09 02:37

Short answer:

This will not work (reliably).

Long answer:

The problem is threefold:

  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

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

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

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'");

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

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

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.

查看更多
兄弟一词,经得起流年.
3楼-- · 2019-07-09 02:44

You can't do that on php level.

The output you get from you call is generated by the shell programm executing your request. That shell is not within php, but a shell controlled on a system and its behavior is also system dependent. You cannot expect the same behavior on your local Linux system as you would get from some Mac system.

If your question is why there are different outputs generated in both cases then the answer is: because different php interpreters are installed. Obviously the shell points you to the one installed and preferred on the system it is running on. Everything else would not make sense. The fact that in the second example php is an alias inside that shell which points to that path is no information of any value on your local Linux system.

查看更多
登录 后发表回答