Как разрешить shell_exec действовать, как если команды выполняются внутри терминала Mac?

Когда я запускаю команду внутри 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 не использует вашу оболочку для входа, но /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 , % 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 , который затем запускает команду.

Хотя вы можете работать с PHP с помощью sh , вторая проблема более серьезная: псевдонимы задаются только в экземпляре, в котором они определены. В большинстве случаев это происходит в некоторых файлах конфигурации (например, ~/.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 

В заключение, это означает, что использование того, which изнутри PHP-скрипта является совершенно ненадежным способом выяснить происхождение / местоположение php . Тем более, что выход зависит от $PATH , который также может быть разным для интерактивных и неинтерактивных оболочек.

Вы не можете сделать это на уровне php.

Вывод, который вы получаете от вашего вызова, генерируется программой оболочки, выполняющей ваш запрос. Эта оболочка не находится в php, но оболочка, управляемая системой, и ее поведение также зависит от системы. Вы не можете ожидать такого же поведения в своей локальной системе Linux, как и в некоторых системах Mac.

Если ваш вопрос заключается в том, почему в обоих случаях возникают разные выходы, тогда ответ будет следующим: поскольку установлены разные интерпретаторы php. Очевидно, что оболочка указывает вам на установленную и привилегированную систему, в которой он работает. Все остальное не имело бы смысла. Тот факт, что во втором примере php является псевдонимом внутри этой оболочки, который указывает на этот путь, не является никакой информацией о какой-либо ценности в вашей локальной системе Linux.