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