Поддерживает ли PHP подстановку процессов?

Я пробовал следующие примеры, такие как:

$ php -r 'require_once($argv[1]);' <(echo "hello")

or:

$ php -r 'file_get_contents($argv[1]);' <(echo "hello")

оба терпят неудачу, как:

Предупреждение PHP: require_once(/dev/fd/63): не удалось открыть поток: нет такого файла или каталога в коде командной строки в строке 1

Предупреждение PHP: file_get_contents(/dev/fd/63): не удалось открыть поток: нет такого файла или каталога в коде командной строки в строке 1

or:

$ php -r 'file_get_contents($argv[0]);' < <(echo "hello")

который терпит неудачу с:

Неустранимая ошибка PHP: require_once(): Не удалось открыть требуемый '-' (include_path='.:/usr/share/pear:/usr/share/php') в коде командной строки в строке 1

Вышеупомянутые попытки были вдохновлены командой drush, например:

$ drush --early=<(echo print 123';') ""
[warning] require_once(/dev/fd/63): failed to open stream: No such file or directory preflight.inc:58

где я мог бы внедрить динамический PHP-код из дескриптора файла (не создавая каждый раз отдельный файл), чтобы выполнить код перед загрузкой основного кода.


Другие подобные командные инструменты работают корректно:

$ cat <(echo "hello")
hello

or:

$ python -c "import sys; print sys.stdin.readlines()" < <(echo "hello")
['hello\n']

Я обнаружил эту ошибку PHP и вот этот, но он давно исправлен, и я использую 5.6.22.

Есть ли способ, которым я могу обмануть PHP в чтении данных из подстановки процесса (для чтения из дескриптора файла, например, /dev/fd) при вызове из CLI, используя какой-то простой однострочный?


person kenorb    schedule 08.08.2016    source источник


Ответы (1)


Сообщение об ошибке дает хорошую подсказку: PHP не может найти данный файл.

Но подождите, какой файл? Итак, давайте вспомним, что такое подстановка процессов:

Подстановка процесса — это форма перенаправления, при которой ввод или вывод процесса (некоторая последовательность команд) отображаются в виде временного файла.

Итак, вы видите, когда печатаете аргумент, который вы предоставляете таким образом:

$ php -r 'print $argv[1];' <(echo "a")

Мне он возвращает следующий временный файл:

/dev/fd/63

Так что да, вы можете использовать подстановку процессов с PHP, но не для этого.

Если вы хотите использовать вывод команды в качестве аргумента, просто используйте $() для его расширения:

$ php -r 'print $argv[1];' "$(echo "hello man")"
hello man
person fedorqui 'SO stop harming'    schedule 08.08.2016
comment
$argv[1] возвращает дескриптор файла (/dev/fd/63), так что это правильно, но я не знаю, почему он не может его прочитать. В вашем последнем примере используется подстановка команд, а не подстановка процессов. Так что мне интересно увидеть пример с подстановкой процесса. - person kenorb; 08.08.2016
comment
@kenorb дело в том, что подстановка процесса здесь предоставляет дескриптор файла, из которого он считывает строку a. Вы не можете заранее определить содержимое файлового дескриптора, чтобы он содержал нужные вам данные. Что именно вы хотите сделать? Укажите переменное имя файла? - person fedorqui 'SO stop harming'; 08.08.2016
comment
Я играл с drush: drush --early=<(echo print 123) "", который выдал мне require_once(/dev/fd/63) ошибку, поэтому мне было интересно, есть ли альтернативный синтаксис, который я мог бы использовать, потому что подстановка команд в этом случае не сработает. Это могло бы быть предметом другого вопроса, но, с другой стороны, было бы слишком похоже на это. В принципе не особо дрочить, а хотелось узнать, может ли PHP поддерживать описания файлов, баг ли это или так задумано. - person kenorb; 08.08.2016
comment
@kenorb Понятно. Я не думаю, что использование подстановки процессов здесь имеет большой смысл, так как обычно это способ обойти конвейеры. Проверьте Подстановка процессов, чтобы найти хорошие примеры. Я бы сосредоточился на том, почему --early="$(echo 123)" не работает, так как подстановка команд кажется более удобной для этого случая: вы хотите, чтобы вывод команды использовался в качестве параметра. - person fedorqui 'SO stop harming'; 08.08.2016
comment
Да, пожалуйста, $(echo 123) будет искать файл 123 в этом синтаксисе, а не в содержимом. - person kenorb; 08.08.2016
comment
@kenorb Я думаю, ключ здесь в следующем: Если подстановка процесса расширяется как аргумент функции, расширяется до переменной среды во время вызова функции или расширяется до любого присваивания внутри функции, подстановка процесса будет остается открытым для использования любой командой внутри функции или ее вызываемых объектов до тех пор, пока функция, в которой она была установлена, не вернется. Если та же самая переменная снова устанавливается в вызываемом объекте, если только новая переменная не является локальной, предыдущая подстановка процесса закрывается и будет недоступна для вызывающего объекта, когда вызываемый объект вернется. То есть это временно. - person fedorqui 'SO stop harming'; 08.08.2016