Когда я запускаю команду внутри 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
Короткий ответ:
Это не сработает (надежно).
Длительный ответ:
Проблема трижды:
/bin/sh
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.