How to open process substituted file from php?












3














Here's what I tried to do myself:



$ type 1.sh
#!/bin/bash -eu
php -r 'var_dump(file_get_contents($_SERVER["argv"][1]));' -- <(echo 1)
$ ./1.sh
PHP Warning: file_get_contents(/dev/fd/63): failed to open stream: No such file or directory in Command line code on line 1

Warning: file_get_contents(/dev/fd/63): failed to open stream: No such file or directory in Command line code on line 1
bool(false)


I tested it on Debian 6 (php-5.4.14, bash-4.1.5) and Arch Linux (php-5.4.12, bash-4.2.42).



UPD



$ strace -f -e trace=file php -r 'var_dump(file_get_contents($_SERVER["argv"][1]));' -- <(echo 1)
...
open("/usr/lib/php5/20100525/mongo.so", O_RDONLY) = 3
lstat("/dev/fd/63", {st_mode=S_IFLNK|0500, st_size=64, ...}) = 0
readlink("/dev/fd/63", "pipe:[405116]"..., 4096) = 13
lstat("/dev/fd/pipe:[405116]", 0x7fff5ea44850) = -1 ENOENT (No such file or directory)
lstat("/dev/fd", {st_mode=S_IFLNK|0777, st_size=13, ...}) = 0
readlink("/dev/fd", "/proc/self/fd"..., 4096) = 13
lstat("/proc/self/fd", {st_mode=S_IFDIR|0500, st_size=0, ...}) = 0
lstat("/proc/self", {st_mode=S_IFLNK|0777, st_size=64, ...}) = 0
readlink("/proc/self", "31536"..., 4096) = 5
lstat("/proc/31536", {st_mode=S_IFDIR|0555, st_size=0, ...}) = 0
lstat("/proc", {st_mode=S_IFDIR|0555, st_size=0, ...}) = 0
open("/proc/31536/fd/pipe:[405116]", O_RDONLY) = -1 ENOENT (No such file or directory)
PHP Warning: file_get_contents(/dev/fd/63): failed to open stream: No such file or directory in Command line code on line 1

Warning: file_get_contents(/dev/fd/63): failed to open stream: No such file or directory in Command line code on line 1
bool(false)

$ strace -f -e trace=file php <(echo 12)
...
open("/usr/lib/php5/20100525/mongo.so", O_RDONLY) = 3
open("/dev/fd/63", O_RDONLY) = 3
lstat("/dev/fd/63", {st_mode=S_IFLNK|0500, st_size=64, ...}) = 0
readlink("/dev/fd/63", "pipe:[413359]", 4096) = 13
lstat("/dev/fd/pipe:[413359]", 0x7fffa69c3c00) = -1 ENOENT (No such file or directory)
lstat("/dev/fd/63", {st_mode=S_IFLNK|0500, st_size=64, ...}) = 0
readlink("/dev/fd/63", "pipe:[413359]", 4096) = 13
lstat("/dev/fd/pipe:[413359]", 0x7fffa69c19b0) = -1 ENOENT (No such file or directory)
lstat("/dev/fd", {st_mode=S_IFLNK|0777, st_size=13, ...}) = 0
readlink("/dev/fd", "/proc/self/fd"..., 4096) = 13
lstat("/proc/self/fd", {st_mode=S_IFDIR|0500, st_size=0, ...}) = 0
lstat("/proc/self", {st_mode=S_IFLNK|0777, st_size=64, ...}) = 0
readlink("/proc/self", "32214"..., 4096) = 5
lstat("/proc/32214", {st_mode=S_IFDIR|0555, st_size=0, ...}) = 0
lstat("/proc", {st_mode=S_IFDIR|0555, st_size=0, ...}) = 0
2









share|improve this question
























  • Do this: strace -f -e trace=file php -r ...
    – Hauke Laging
    May 3 '13 at 19:23










  • I added output of strace to the question, please take a look.
    – x-yuri
    May 3 '13 at 22:25










  • Process Substitution -- <(cmd) and >(cmd), See mywiki.wooledge.org/BashSheet#Expansions mywiki.wooledge.org/ProcessSubstitution mywiki.wooledge.org/BashFAQ/024
    – Rany Albeg Wein
    May 3 '13 at 22:31






  • 1




    @Rany Albeg Wein What exactly do you mean with your links? Are there any information explaining the issue?
    – x-yuri
    May 4 '13 at 9:43
















3














Here's what I tried to do myself:



$ type 1.sh
#!/bin/bash -eu
php -r 'var_dump(file_get_contents($_SERVER["argv"][1]));' -- <(echo 1)
$ ./1.sh
PHP Warning: file_get_contents(/dev/fd/63): failed to open stream: No such file or directory in Command line code on line 1

Warning: file_get_contents(/dev/fd/63): failed to open stream: No such file or directory in Command line code on line 1
bool(false)


I tested it on Debian 6 (php-5.4.14, bash-4.1.5) and Arch Linux (php-5.4.12, bash-4.2.42).



UPD



$ strace -f -e trace=file php -r 'var_dump(file_get_contents($_SERVER["argv"][1]));' -- <(echo 1)
...
open("/usr/lib/php5/20100525/mongo.so", O_RDONLY) = 3
lstat("/dev/fd/63", {st_mode=S_IFLNK|0500, st_size=64, ...}) = 0
readlink("/dev/fd/63", "pipe:[405116]"..., 4096) = 13
lstat("/dev/fd/pipe:[405116]", 0x7fff5ea44850) = -1 ENOENT (No such file or directory)
lstat("/dev/fd", {st_mode=S_IFLNK|0777, st_size=13, ...}) = 0
readlink("/dev/fd", "/proc/self/fd"..., 4096) = 13
lstat("/proc/self/fd", {st_mode=S_IFDIR|0500, st_size=0, ...}) = 0
lstat("/proc/self", {st_mode=S_IFLNK|0777, st_size=64, ...}) = 0
readlink("/proc/self", "31536"..., 4096) = 5
lstat("/proc/31536", {st_mode=S_IFDIR|0555, st_size=0, ...}) = 0
lstat("/proc", {st_mode=S_IFDIR|0555, st_size=0, ...}) = 0
open("/proc/31536/fd/pipe:[405116]", O_RDONLY) = -1 ENOENT (No such file or directory)
PHP Warning: file_get_contents(/dev/fd/63): failed to open stream: No such file or directory in Command line code on line 1

Warning: file_get_contents(/dev/fd/63): failed to open stream: No such file or directory in Command line code on line 1
bool(false)

$ strace -f -e trace=file php <(echo 12)
...
open("/usr/lib/php5/20100525/mongo.so", O_RDONLY) = 3
open("/dev/fd/63", O_RDONLY) = 3
lstat("/dev/fd/63", {st_mode=S_IFLNK|0500, st_size=64, ...}) = 0
readlink("/dev/fd/63", "pipe:[413359]", 4096) = 13
lstat("/dev/fd/pipe:[413359]", 0x7fffa69c3c00) = -1 ENOENT (No such file or directory)
lstat("/dev/fd/63", {st_mode=S_IFLNK|0500, st_size=64, ...}) = 0
readlink("/dev/fd/63", "pipe:[413359]", 4096) = 13
lstat("/dev/fd/pipe:[413359]", 0x7fffa69c19b0) = -1 ENOENT (No such file or directory)
lstat("/dev/fd", {st_mode=S_IFLNK|0777, st_size=13, ...}) = 0
readlink("/dev/fd", "/proc/self/fd"..., 4096) = 13
lstat("/proc/self/fd", {st_mode=S_IFDIR|0500, st_size=0, ...}) = 0
lstat("/proc/self", {st_mode=S_IFLNK|0777, st_size=64, ...}) = 0
readlink("/proc/self", "32214"..., 4096) = 5
lstat("/proc/32214", {st_mode=S_IFDIR|0555, st_size=0, ...}) = 0
lstat("/proc", {st_mode=S_IFDIR|0555, st_size=0, ...}) = 0
2









share|improve this question
























  • Do this: strace -f -e trace=file php -r ...
    – Hauke Laging
    May 3 '13 at 19:23










  • I added output of strace to the question, please take a look.
    – x-yuri
    May 3 '13 at 22:25










  • Process Substitution -- <(cmd) and >(cmd), See mywiki.wooledge.org/BashSheet#Expansions mywiki.wooledge.org/ProcessSubstitution mywiki.wooledge.org/BashFAQ/024
    – Rany Albeg Wein
    May 3 '13 at 22:31






  • 1




    @Rany Albeg Wein What exactly do you mean with your links? Are there any information explaining the issue?
    – x-yuri
    May 4 '13 at 9:43














3












3








3







Here's what I tried to do myself:



$ type 1.sh
#!/bin/bash -eu
php -r 'var_dump(file_get_contents($_SERVER["argv"][1]));' -- <(echo 1)
$ ./1.sh
PHP Warning: file_get_contents(/dev/fd/63): failed to open stream: No such file or directory in Command line code on line 1

Warning: file_get_contents(/dev/fd/63): failed to open stream: No such file or directory in Command line code on line 1
bool(false)


I tested it on Debian 6 (php-5.4.14, bash-4.1.5) and Arch Linux (php-5.4.12, bash-4.2.42).



UPD



$ strace -f -e trace=file php -r 'var_dump(file_get_contents($_SERVER["argv"][1]));' -- <(echo 1)
...
open("/usr/lib/php5/20100525/mongo.so", O_RDONLY) = 3
lstat("/dev/fd/63", {st_mode=S_IFLNK|0500, st_size=64, ...}) = 0
readlink("/dev/fd/63", "pipe:[405116]"..., 4096) = 13
lstat("/dev/fd/pipe:[405116]", 0x7fff5ea44850) = -1 ENOENT (No such file or directory)
lstat("/dev/fd", {st_mode=S_IFLNK|0777, st_size=13, ...}) = 0
readlink("/dev/fd", "/proc/self/fd"..., 4096) = 13
lstat("/proc/self/fd", {st_mode=S_IFDIR|0500, st_size=0, ...}) = 0
lstat("/proc/self", {st_mode=S_IFLNK|0777, st_size=64, ...}) = 0
readlink("/proc/self", "31536"..., 4096) = 5
lstat("/proc/31536", {st_mode=S_IFDIR|0555, st_size=0, ...}) = 0
lstat("/proc", {st_mode=S_IFDIR|0555, st_size=0, ...}) = 0
open("/proc/31536/fd/pipe:[405116]", O_RDONLY) = -1 ENOENT (No such file or directory)
PHP Warning: file_get_contents(/dev/fd/63): failed to open stream: No such file or directory in Command line code on line 1

Warning: file_get_contents(/dev/fd/63): failed to open stream: No such file or directory in Command line code on line 1
bool(false)

$ strace -f -e trace=file php <(echo 12)
...
open("/usr/lib/php5/20100525/mongo.so", O_RDONLY) = 3
open("/dev/fd/63", O_RDONLY) = 3
lstat("/dev/fd/63", {st_mode=S_IFLNK|0500, st_size=64, ...}) = 0
readlink("/dev/fd/63", "pipe:[413359]", 4096) = 13
lstat("/dev/fd/pipe:[413359]", 0x7fffa69c3c00) = -1 ENOENT (No such file or directory)
lstat("/dev/fd/63", {st_mode=S_IFLNK|0500, st_size=64, ...}) = 0
readlink("/dev/fd/63", "pipe:[413359]", 4096) = 13
lstat("/dev/fd/pipe:[413359]", 0x7fffa69c19b0) = -1 ENOENT (No such file or directory)
lstat("/dev/fd", {st_mode=S_IFLNK|0777, st_size=13, ...}) = 0
readlink("/dev/fd", "/proc/self/fd"..., 4096) = 13
lstat("/proc/self/fd", {st_mode=S_IFDIR|0500, st_size=0, ...}) = 0
lstat("/proc/self", {st_mode=S_IFLNK|0777, st_size=64, ...}) = 0
readlink("/proc/self", "32214"..., 4096) = 5
lstat("/proc/32214", {st_mode=S_IFDIR|0555, st_size=0, ...}) = 0
lstat("/proc", {st_mode=S_IFDIR|0555, st_size=0, ...}) = 0
2









share|improve this question















Here's what I tried to do myself:



$ type 1.sh
#!/bin/bash -eu
php -r 'var_dump(file_get_contents($_SERVER["argv"][1]));' -- <(echo 1)
$ ./1.sh
PHP Warning: file_get_contents(/dev/fd/63): failed to open stream: No such file or directory in Command line code on line 1

Warning: file_get_contents(/dev/fd/63): failed to open stream: No such file or directory in Command line code on line 1
bool(false)


I tested it on Debian 6 (php-5.4.14, bash-4.1.5) and Arch Linux (php-5.4.12, bash-4.2.42).



UPD



$ strace -f -e trace=file php -r 'var_dump(file_get_contents($_SERVER["argv"][1]));' -- <(echo 1)
...
open("/usr/lib/php5/20100525/mongo.so", O_RDONLY) = 3
lstat("/dev/fd/63", {st_mode=S_IFLNK|0500, st_size=64, ...}) = 0
readlink("/dev/fd/63", "pipe:[405116]"..., 4096) = 13
lstat("/dev/fd/pipe:[405116]", 0x7fff5ea44850) = -1 ENOENT (No such file or directory)
lstat("/dev/fd", {st_mode=S_IFLNK|0777, st_size=13, ...}) = 0
readlink("/dev/fd", "/proc/self/fd"..., 4096) = 13
lstat("/proc/self/fd", {st_mode=S_IFDIR|0500, st_size=0, ...}) = 0
lstat("/proc/self", {st_mode=S_IFLNK|0777, st_size=64, ...}) = 0
readlink("/proc/self", "31536"..., 4096) = 5
lstat("/proc/31536", {st_mode=S_IFDIR|0555, st_size=0, ...}) = 0
lstat("/proc", {st_mode=S_IFDIR|0555, st_size=0, ...}) = 0
open("/proc/31536/fd/pipe:[405116]", O_RDONLY) = -1 ENOENT (No such file or directory)
PHP Warning: file_get_contents(/dev/fd/63): failed to open stream: No such file or directory in Command line code on line 1

Warning: file_get_contents(/dev/fd/63): failed to open stream: No such file or directory in Command line code on line 1
bool(false)

$ strace -f -e trace=file php <(echo 12)
...
open("/usr/lib/php5/20100525/mongo.so", O_RDONLY) = 3
open("/dev/fd/63", O_RDONLY) = 3
lstat("/dev/fd/63", {st_mode=S_IFLNK|0500, st_size=64, ...}) = 0
readlink("/dev/fd/63", "pipe:[413359]", 4096) = 13
lstat("/dev/fd/pipe:[413359]", 0x7fffa69c3c00) = -1 ENOENT (No such file or directory)
lstat("/dev/fd/63", {st_mode=S_IFLNK|0500, st_size=64, ...}) = 0
readlink("/dev/fd/63", "pipe:[413359]", 4096) = 13
lstat("/dev/fd/pipe:[413359]", 0x7fffa69c19b0) = -1 ENOENT (No such file or directory)
lstat("/dev/fd", {st_mode=S_IFLNK|0777, st_size=13, ...}) = 0
readlink("/dev/fd", "/proc/self/fd"..., 4096) = 13
lstat("/proc/self/fd", {st_mode=S_IFDIR|0500, st_size=0, ...}) = 0
lstat("/proc/self", {st_mode=S_IFLNK|0777, st_size=64, ...}) = 0
readlink("/proc/self", "32214"..., 4096) = 5
lstat("/proc/32214", {st_mode=S_IFDIR|0555, st_size=0, ...}) = 0
lstat("/proc", {st_mode=S_IFDIR|0555, st_size=0, ...}) = 0
2






bash shell php process-substitution






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited May 5 '13 at 13:39

























asked May 3 '13 at 18:52









x-yuri

1,17311642




1,17311642












  • Do this: strace -f -e trace=file php -r ...
    – Hauke Laging
    May 3 '13 at 19:23










  • I added output of strace to the question, please take a look.
    – x-yuri
    May 3 '13 at 22:25










  • Process Substitution -- <(cmd) and >(cmd), See mywiki.wooledge.org/BashSheet#Expansions mywiki.wooledge.org/ProcessSubstitution mywiki.wooledge.org/BashFAQ/024
    – Rany Albeg Wein
    May 3 '13 at 22:31






  • 1




    @Rany Albeg Wein What exactly do you mean with your links? Are there any information explaining the issue?
    – x-yuri
    May 4 '13 at 9:43


















  • Do this: strace -f -e trace=file php -r ...
    – Hauke Laging
    May 3 '13 at 19:23










  • I added output of strace to the question, please take a look.
    – x-yuri
    May 3 '13 at 22:25










  • Process Substitution -- <(cmd) and >(cmd), See mywiki.wooledge.org/BashSheet#Expansions mywiki.wooledge.org/ProcessSubstitution mywiki.wooledge.org/BashFAQ/024
    – Rany Albeg Wein
    May 3 '13 at 22:31






  • 1




    @Rany Albeg Wein What exactly do you mean with your links? Are there any information explaining the issue?
    – x-yuri
    May 4 '13 at 9:43
















Do this: strace -f -e trace=file php -r ...
– Hauke Laging
May 3 '13 at 19:23




Do this: strace -f -e trace=file php -r ...
– Hauke Laging
May 3 '13 at 19:23












I added output of strace to the question, please take a look.
– x-yuri
May 3 '13 at 22:25




I added output of strace to the question, please take a look.
– x-yuri
May 3 '13 at 22:25












Process Substitution -- <(cmd) and >(cmd), See mywiki.wooledge.org/BashSheet#Expansions mywiki.wooledge.org/ProcessSubstitution mywiki.wooledge.org/BashFAQ/024
– Rany Albeg Wein
May 3 '13 at 22:31




Process Substitution -- <(cmd) and >(cmd), See mywiki.wooledge.org/BashSheet#Expansions mywiki.wooledge.org/ProcessSubstitution mywiki.wooledge.org/BashFAQ/024
– Rany Albeg Wein
May 3 '13 at 22:31




1




1




@Rany Albeg Wein What exactly do you mean with your links? Are there any information explaining the issue?
– x-yuri
May 4 '13 at 9:43




@Rany Albeg Wein What exactly do you mean with your links? Are there any information explaining the issue?
– x-yuri
May 4 '13 at 9:43










4 Answers
4






active

oldest

votes


















2














The problem is you want php to read input from a file descriptor, but you force it to read like regular file.



First, try this:



$ echo <(ls)
/dev/fd/63


then you can process ls output by reading /dev/fd/63. The process substitution will return the file descriptor, which is use by other command to reading its output.



In your case, you use $_SERVER["argv"][1], meaning that php will interpreter like this:



file_get_contents(/dev/fd/63)


From php manual, you can see protorype of file_get_contents function:



string file_get_contents ( string $filename [, bool $use_include_path =
false [, resource $context [, int $offset = -1 [, int $maxlen ]]]] )


Ops, php will consider /dev/fd/63 as normal file here, but it's really a file descriptor.



To access file descriptor, you must use php://fd, php://fd/63 will access content of file descriptor 63:



$ php -r 'var_dump(file_get_contents("php://".substr($_SERVER["argv"][1],-5)));' -- <(echo test.txt)
string(9) "test.txt
"


You can see, now php can process content in /dev/fd/63. But our purpose is reading content of file, which is provide via process substitution (In my example, it's test.txt). I don't know much about php, so I add another file_get_contents:



$ php -r 'var_dump(file_get_contents(file_get_contents("php://".substr($_SERVER["argv"][1],-5))));' -- <(echo -n test.txt)
string(13) "Hello world!
"


I use echo -n to remove newline from echo ouput, otherwise, php will see the ouput "test.txtn".



Note



For more information about accessing file descriptor in php, you can see here.






share|improve this answer























  • This clears things up a bit. But the important thing here is why can't php do as everybody does and just open the file? Like: cat <(echo test). Also, you're wrong about your wording. I don't want php to read input from a file descriptor, process substitution doesn't return file descriptors and so on. /dev/fd/* files are files of procfs (virtual filesystem), which correspond to file descriptors of the process. You can't open file descriptor. They are means by which we specify to the kernel, what open file we're talking about.
    – x-yuri
    Apr 15 '14 at 20:34












  • What do you mean "everybody"?cat <(echo test) meaning cat /dev/fd/63 and will print test because cat have done its job, like you do cat /path/to/regular_file. You can see more here - en.wikipedia.org/wiki/Process_substitution - to know why process substitution return a file descriptor.
    – cuonglm
    Apr 16 '14 at 1:38










  • Let's see: ruby -e 'p File.read ARGV[0]' <(echo test), perl -e 'open F, @ARGV[0]; print <F>' <(echo test), cat <(echo test). They all don't try to dereference the link and just output what they're asked. As opposed to php. Because that's what open system call does. Do you have any counterexamples? Also, your wikipedia article has no word descriptor in it. Process substitution returns a symbolic link to non-existent file, which corresponds to a file descriptor.
    – x-yuri
    Apr 16 '14 at 6:11












  • @x-yuri: You should reading the article carefully, esspecially section Limitations. And you should know ruby File.read, perl diamond operator <> is very different with php file_get_contents.
    – cuonglm
    Apr 16 '14 at 6:35










  • I'd read that article before you mentioned it. And I understand that the pipes are not seekable, and therefore not all the programs will be able to work with process substitution. The question is why exactly php can't work with process substitution, what prevents it from doing that? perl, ruby, bash and whatnot deal with it just fine. Do you know any other languages with similar problems? Also, I do understand that File.read and <> are different from file_get_contents, but not in the context of the discussion. Considering the topic, they just read a file.
    – x-yuri
    Apr 16 '14 at 11:02



















1














This is the problem:



readlink("/dev/fd/63", "pipe:[405116]"..., 4096) = 13
lstat("/dev/fd/pipe:[405116]", 0x7fff5ea44850) = -1 ENOENT


Without any good reason (IMHO) php tries to get the real name of the link target. Unfortunately the link target is not part of the file system thus the try to access that name fails and causes this error. The symlink can only be opened as such. I consider this a bug in php. You could use a FIFO instead:



mkfifo /my/fifo; output_cmd >/my/fifo & php -r ... /my/fifo





share|improve this answer





















  • But php, opening the file on its own, makes the same system calls and the file is opened successfully. See updated question.
    – x-yuri
    May 4 '13 at 9:38










  • @x-yuri There is neither a "file" nor "on its own". In both cases there is a lstat("/dev/fd/pipe:[405116]", 0x7fff5ea44850) = -1 ENOENT call. Unfortunately the second block ends one line too early. What does the open() call to the file look like? Maybe php can be tricked into opening the link path instead of the "physical" path. But that cannot be forced from the outside.
    – Hauke Laging
    May 4 '13 at 12:56










  • There is no more system calls for php <(echo 12) case. I only forgot to add output of the script itself.
    – x-yuri
    May 5 '13 at 13:51










  • @x-yuri The file is obviously not opened if there is no open() or openat(). The missing error message does not mean that the file was opened successfully.
    – Hauke Laging
    May 5 '13 at 14:02










  • I meant, there is only one call to open(), on the second line of the output (open("/dev/fd/63"...) . Not at the end. So, the file is opened. And the script is run, so the file is opened successfully. Just in case... do note who tries to open the file: php -r '...file_get_contents(...' -- <(echo 12) - the file is opened by the script. php <(echo 12) - the file is opened by php itself and contains the script.
    – x-yuri
    May 5 '13 at 15:23





















0














Here's what I ended up using...



php -r "var_dump(file_get_contents('php://stdin'));" < <(echo this is a win)


If you're trying to do other stuff with stdin this obviously won't work for you, and this is no different from



php -r "var_dump(stream_get_contents(STDIN));" < <(echo this is a win)


which leads me to wonder what it is you were actually trying to do, and why are you stuck on file_get_contents? :)



Reference - http://php.net/manual/en/wrappers.php.php






share|improve this answer





















  • I was trying to embed php script into bash script, see my first question.
    – x-yuri
    May 27 '16 at 19:03



















0














This is an old question but I just figured out the answer so I thought I'd share. Maybe it will help someone.



You can use the php:// stream wrapper to open the file descriptor instead:



 $fd = $argv[1];
$handle = fopen(str_replace('/dev/','php://',$fd));


So instead of opening the /dev/fd/[nn] file descriptor provided by the OS. You'll be opening php://fd/[nn] which will work. I'm not sure why opening the file descriptor fails on some systems but not others.



This was an old bug and was supposed to have been fixed.






share|improve this answer





















    Your Answer








    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "106"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: false,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: null,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














    draft saved

    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f74604%2fhow-to-open-process-substituted-file-from-php%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    4 Answers
    4






    active

    oldest

    votes








    4 Answers
    4






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    2














    The problem is you want php to read input from a file descriptor, but you force it to read like regular file.



    First, try this:



    $ echo <(ls)
    /dev/fd/63


    then you can process ls output by reading /dev/fd/63. The process substitution will return the file descriptor, which is use by other command to reading its output.



    In your case, you use $_SERVER["argv"][1], meaning that php will interpreter like this:



    file_get_contents(/dev/fd/63)


    From php manual, you can see protorype of file_get_contents function:



    string file_get_contents ( string $filename [, bool $use_include_path =
    false [, resource $context [, int $offset = -1 [, int $maxlen ]]]] )


    Ops, php will consider /dev/fd/63 as normal file here, but it's really a file descriptor.



    To access file descriptor, you must use php://fd, php://fd/63 will access content of file descriptor 63:



    $ php -r 'var_dump(file_get_contents("php://".substr($_SERVER["argv"][1],-5)));' -- <(echo test.txt)
    string(9) "test.txt
    "


    You can see, now php can process content in /dev/fd/63. But our purpose is reading content of file, which is provide via process substitution (In my example, it's test.txt). I don't know much about php, so I add another file_get_contents:



    $ php -r 'var_dump(file_get_contents(file_get_contents("php://".substr($_SERVER["argv"][1],-5))));' -- <(echo -n test.txt)
    string(13) "Hello world!
    "


    I use echo -n to remove newline from echo ouput, otherwise, php will see the ouput "test.txtn".



    Note



    For more information about accessing file descriptor in php, you can see here.






    share|improve this answer























    • This clears things up a bit. But the important thing here is why can't php do as everybody does and just open the file? Like: cat <(echo test). Also, you're wrong about your wording. I don't want php to read input from a file descriptor, process substitution doesn't return file descriptors and so on. /dev/fd/* files are files of procfs (virtual filesystem), which correspond to file descriptors of the process. You can't open file descriptor. They are means by which we specify to the kernel, what open file we're talking about.
      – x-yuri
      Apr 15 '14 at 20:34












    • What do you mean "everybody"?cat <(echo test) meaning cat /dev/fd/63 and will print test because cat have done its job, like you do cat /path/to/regular_file. You can see more here - en.wikipedia.org/wiki/Process_substitution - to know why process substitution return a file descriptor.
      – cuonglm
      Apr 16 '14 at 1:38










    • Let's see: ruby -e 'p File.read ARGV[0]' <(echo test), perl -e 'open F, @ARGV[0]; print <F>' <(echo test), cat <(echo test). They all don't try to dereference the link and just output what they're asked. As opposed to php. Because that's what open system call does. Do you have any counterexamples? Also, your wikipedia article has no word descriptor in it. Process substitution returns a symbolic link to non-existent file, which corresponds to a file descriptor.
      – x-yuri
      Apr 16 '14 at 6:11












    • @x-yuri: You should reading the article carefully, esspecially section Limitations. And you should know ruby File.read, perl diamond operator <> is very different with php file_get_contents.
      – cuonglm
      Apr 16 '14 at 6:35










    • I'd read that article before you mentioned it. And I understand that the pipes are not seekable, and therefore not all the programs will be able to work with process substitution. The question is why exactly php can't work with process substitution, what prevents it from doing that? perl, ruby, bash and whatnot deal with it just fine. Do you know any other languages with similar problems? Also, I do understand that File.read and <> are different from file_get_contents, but not in the context of the discussion. Considering the topic, they just read a file.
      – x-yuri
      Apr 16 '14 at 11:02
















    2














    The problem is you want php to read input from a file descriptor, but you force it to read like regular file.



    First, try this:



    $ echo <(ls)
    /dev/fd/63


    then you can process ls output by reading /dev/fd/63. The process substitution will return the file descriptor, which is use by other command to reading its output.



    In your case, you use $_SERVER["argv"][1], meaning that php will interpreter like this:



    file_get_contents(/dev/fd/63)


    From php manual, you can see protorype of file_get_contents function:



    string file_get_contents ( string $filename [, bool $use_include_path =
    false [, resource $context [, int $offset = -1 [, int $maxlen ]]]] )


    Ops, php will consider /dev/fd/63 as normal file here, but it's really a file descriptor.



    To access file descriptor, you must use php://fd, php://fd/63 will access content of file descriptor 63:



    $ php -r 'var_dump(file_get_contents("php://".substr($_SERVER["argv"][1],-5)));' -- <(echo test.txt)
    string(9) "test.txt
    "


    You can see, now php can process content in /dev/fd/63. But our purpose is reading content of file, which is provide via process substitution (In my example, it's test.txt). I don't know much about php, so I add another file_get_contents:



    $ php -r 'var_dump(file_get_contents(file_get_contents("php://".substr($_SERVER["argv"][1],-5))));' -- <(echo -n test.txt)
    string(13) "Hello world!
    "


    I use echo -n to remove newline from echo ouput, otherwise, php will see the ouput "test.txtn".



    Note



    For more information about accessing file descriptor in php, you can see here.






    share|improve this answer























    • This clears things up a bit. But the important thing here is why can't php do as everybody does and just open the file? Like: cat <(echo test). Also, you're wrong about your wording. I don't want php to read input from a file descriptor, process substitution doesn't return file descriptors and so on. /dev/fd/* files are files of procfs (virtual filesystem), which correspond to file descriptors of the process. You can't open file descriptor. They are means by which we specify to the kernel, what open file we're talking about.
      – x-yuri
      Apr 15 '14 at 20:34












    • What do you mean "everybody"?cat <(echo test) meaning cat /dev/fd/63 and will print test because cat have done its job, like you do cat /path/to/regular_file. You can see more here - en.wikipedia.org/wiki/Process_substitution - to know why process substitution return a file descriptor.
      – cuonglm
      Apr 16 '14 at 1:38










    • Let's see: ruby -e 'p File.read ARGV[0]' <(echo test), perl -e 'open F, @ARGV[0]; print <F>' <(echo test), cat <(echo test). They all don't try to dereference the link and just output what they're asked. As opposed to php. Because that's what open system call does. Do you have any counterexamples? Also, your wikipedia article has no word descriptor in it. Process substitution returns a symbolic link to non-existent file, which corresponds to a file descriptor.
      – x-yuri
      Apr 16 '14 at 6:11












    • @x-yuri: You should reading the article carefully, esspecially section Limitations. And you should know ruby File.read, perl diamond operator <> is very different with php file_get_contents.
      – cuonglm
      Apr 16 '14 at 6:35










    • I'd read that article before you mentioned it. And I understand that the pipes are not seekable, and therefore not all the programs will be able to work with process substitution. The question is why exactly php can't work with process substitution, what prevents it from doing that? perl, ruby, bash and whatnot deal with it just fine. Do you know any other languages with similar problems? Also, I do understand that File.read and <> are different from file_get_contents, but not in the context of the discussion. Considering the topic, they just read a file.
      – x-yuri
      Apr 16 '14 at 11:02














    2












    2








    2






    The problem is you want php to read input from a file descriptor, but you force it to read like regular file.



    First, try this:



    $ echo <(ls)
    /dev/fd/63


    then you can process ls output by reading /dev/fd/63. The process substitution will return the file descriptor, which is use by other command to reading its output.



    In your case, you use $_SERVER["argv"][1], meaning that php will interpreter like this:



    file_get_contents(/dev/fd/63)


    From php manual, you can see protorype of file_get_contents function:



    string file_get_contents ( string $filename [, bool $use_include_path =
    false [, resource $context [, int $offset = -1 [, int $maxlen ]]]] )


    Ops, php will consider /dev/fd/63 as normal file here, but it's really a file descriptor.



    To access file descriptor, you must use php://fd, php://fd/63 will access content of file descriptor 63:



    $ php -r 'var_dump(file_get_contents("php://".substr($_SERVER["argv"][1],-5)));' -- <(echo test.txt)
    string(9) "test.txt
    "


    You can see, now php can process content in /dev/fd/63. But our purpose is reading content of file, which is provide via process substitution (In my example, it's test.txt). I don't know much about php, so I add another file_get_contents:



    $ php -r 'var_dump(file_get_contents(file_get_contents("php://".substr($_SERVER["argv"][1],-5))));' -- <(echo -n test.txt)
    string(13) "Hello world!
    "


    I use echo -n to remove newline from echo ouput, otherwise, php will see the ouput "test.txtn".



    Note



    For more information about accessing file descriptor in php, you can see here.






    share|improve this answer














    The problem is you want php to read input from a file descriptor, but you force it to read like regular file.



    First, try this:



    $ echo <(ls)
    /dev/fd/63


    then you can process ls output by reading /dev/fd/63. The process substitution will return the file descriptor, which is use by other command to reading its output.



    In your case, you use $_SERVER["argv"][1], meaning that php will interpreter like this:



    file_get_contents(/dev/fd/63)


    From php manual, you can see protorype of file_get_contents function:



    string file_get_contents ( string $filename [, bool $use_include_path =
    false [, resource $context [, int $offset = -1 [, int $maxlen ]]]] )


    Ops, php will consider /dev/fd/63 as normal file here, but it's really a file descriptor.



    To access file descriptor, you must use php://fd, php://fd/63 will access content of file descriptor 63:



    $ php -r 'var_dump(file_get_contents("php://".substr($_SERVER["argv"][1],-5)));' -- <(echo test.txt)
    string(9) "test.txt
    "


    You can see, now php can process content in /dev/fd/63. But our purpose is reading content of file, which is provide via process substitution (In my example, it's test.txt). I don't know much about php, so I add another file_get_contents:



    $ php -r 'var_dump(file_get_contents(file_get_contents("php://".substr($_SERVER["argv"][1],-5))));' -- <(echo -n test.txt)
    string(13) "Hello world!
    "


    I use echo -n to remove newline from echo ouput, otherwise, php will see the ouput "test.txtn".



    Note



    For more information about accessing file descriptor in php, you can see here.







    share|improve this answer














    share|improve this answer



    share|improve this answer








    edited Apr 15 '14 at 4:24

























    answered Apr 15 '14 at 3:55









    cuonglm

    102k23201301




    102k23201301












    • This clears things up a bit. But the important thing here is why can't php do as everybody does and just open the file? Like: cat <(echo test). Also, you're wrong about your wording. I don't want php to read input from a file descriptor, process substitution doesn't return file descriptors and so on. /dev/fd/* files are files of procfs (virtual filesystem), which correspond to file descriptors of the process. You can't open file descriptor. They are means by which we specify to the kernel, what open file we're talking about.
      – x-yuri
      Apr 15 '14 at 20:34












    • What do you mean "everybody"?cat <(echo test) meaning cat /dev/fd/63 and will print test because cat have done its job, like you do cat /path/to/regular_file. You can see more here - en.wikipedia.org/wiki/Process_substitution - to know why process substitution return a file descriptor.
      – cuonglm
      Apr 16 '14 at 1:38










    • Let's see: ruby -e 'p File.read ARGV[0]' <(echo test), perl -e 'open F, @ARGV[0]; print <F>' <(echo test), cat <(echo test). They all don't try to dereference the link and just output what they're asked. As opposed to php. Because that's what open system call does. Do you have any counterexamples? Also, your wikipedia article has no word descriptor in it. Process substitution returns a symbolic link to non-existent file, which corresponds to a file descriptor.
      – x-yuri
      Apr 16 '14 at 6:11












    • @x-yuri: You should reading the article carefully, esspecially section Limitations. And you should know ruby File.read, perl diamond operator <> is very different with php file_get_contents.
      – cuonglm
      Apr 16 '14 at 6:35










    • I'd read that article before you mentioned it. And I understand that the pipes are not seekable, and therefore not all the programs will be able to work with process substitution. The question is why exactly php can't work with process substitution, what prevents it from doing that? perl, ruby, bash and whatnot deal with it just fine. Do you know any other languages with similar problems? Also, I do understand that File.read and <> are different from file_get_contents, but not in the context of the discussion. Considering the topic, they just read a file.
      – x-yuri
      Apr 16 '14 at 11:02


















    • This clears things up a bit. But the important thing here is why can't php do as everybody does and just open the file? Like: cat <(echo test). Also, you're wrong about your wording. I don't want php to read input from a file descriptor, process substitution doesn't return file descriptors and so on. /dev/fd/* files are files of procfs (virtual filesystem), which correspond to file descriptors of the process. You can't open file descriptor. They are means by which we specify to the kernel, what open file we're talking about.
      – x-yuri
      Apr 15 '14 at 20:34












    • What do you mean "everybody"?cat <(echo test) meaning cat /dev/fd/63 and will print test because cat have done its job, like you do cat /path/to/regular_file. You can see more here - en.wikipedia.org/wiki/Process_substitution - to know why process substitution return a file descriptor.
      – cuonglm
      Apr 16 '14 at 1:38










    • Let's see: ruby -e 'p File.read ARGV[0]' <(echo test), perl -e 'open F, @ARGV[0]; print <F>' <(echo test), cat <(echo test). They all don't try to dereference the link and just output what they're asked. As opposed to php. Because that's what open system call does. Do you have any counterexamples? Also, your wikipedia article has no word descriptor in it. Process substitution returns a symbolic link to non-existent file, which corresponds to a file descriptor.
      – x-yuri
      Apr 16 '14 at 6:11












    • @x-yuri: You should reading the article carefully, esspecially section Limitations. And you should know ruby File.read, perl diamond operator <> is very different with php file_get_contents.
      – cuonglm
      Apr 16 '14 at 6:35










    • I'd read that article before you mentioned it. And I understand that the pipes are not seekable, and therefore not all the programs will be able to work with process substitution. The question is why exactly php can't work with process substitution, what prevents it from doing that? perl, ruby, bash and whatnot deal with it just fine. Do you know any other languages with similar problems? Also, I do understand that File.read and <> are different from file_get_contents, but not in the context of the discussion. Considering the topic, they just read a file.
      – x-yuri
      Apr 16 '14 at 11:02
















    This clears things up a bit. But the important thing here is why can't php do as everybody does and just open the file? Like: cat <(echo test). Also, you're wrong about your wording. I don't want php to read input from a file descriptor, process substitution doesn't return file descriptors and so on. /dev/fd/* files are files of procfs (virtual filesystem), which correspond to file descriptors of the process. You can't open file descriptor. They are means by which we specify to the kernel, what open file we're talking about.
    – x-yuri
    Apr 15 '14 at 20:34






    This clears things up a bit. But the important thing here is why can't php do as everybody does and just open the file? Like: cat <(echo test). Also, you're wrong about your wording. I don't want php to read input from a file descriptor, process substitution doesn't return file descriptors and so on. /dev/fd/* files are files of procfs (virtual filesystem), which correspond to file descriptors of the process. You can't open file descriptor. They are means by which we specify to the kernel, what open file we're talking about.
    – x-yuri
    Apr 15 '14 at 20:34














    What do you mean "everybody"?cat <(echo test) meaning cat /dev/fd/63 and will print test because cat have done its job, like you do cat /path/to/regular_file. You can see more here - en.wikipedia.org/wiki/Process_substitution - to know why process substitution return a file descriptor.
    – cuonglm
    Apr 16 '14 at 1:38




    What do you mean "everybody"?cat <(echo test) meaning cat /dev/fd/63 and will print test because cat have done its job, like you do cat /path/to/regular_file. You can see more here - en.wikipedia.org/wiki/Process_substitution - to know why process substitution return a file descriptor.
    – cuonglm
    Apr 16 '14 at 1:38












    Let's see: ruby -e 'p File.read ARGV[0]' <(echo test), perl -e 'open F, @ARGV[0]; print <F>' <(echo test), cat <(echo test). They all don't try to dereference the link and just output what they're asked. As opposed to php. Because that's what open system call does. Do you have any counterexamples? Also, your wikipedia article has no word descriptor in it. Process substitution returns a symbolic link to non-existent file, which corresponds to a file descriptor.
    – x-yuri
    Apr 16 '14 at 6:11






    Let's see: ruby -e 'p File.read ARGV[0]' <(echo test), perl -e 'open F, @ARGV[0]; print <F>' <(echo test), cat <(echo test). They all don't try to dereference the link and just output what they're asked. As opposed to php. Because that's what open system call does. Do you have any counterexamples? Also, your wikipedia article has no word descriptor in it. Process substitution returns a symbolic link to non-existent file, which corresponds to a file descriptor.
    – x-yuri
    Apr 16 '14 at 6:11














    @x-yuri: You should reading the article carefully, esspecially section Limitations. And you should know ruby File.read, perl diamond operator <> is very different with php file_get_contents.
    – cuonglm
    Apr 16 '14 at 6:35




    @x-yuri: You should reading the article carefully, esspecially section Limitations. And you should know ruby File.read, perl diamond operator <> is very different with php file_get_contents.
    – cuonglm
    Apr 16 '14 at 6:35












    I'd read that article before you mentioned it. And I understand that the pipes are not seekable, and therefore not all the programs will be able to work with process substitution. The question is why exactly php can't work with process substitution, what prevents it from doing that? perl, ruby, bash and whatnot deal with it just fine. Do you know any other languages with similar problems? Also, I do understand that File.read and <> are different from file_get_contents, but not in the context of the discussion. Considering the topic, they just read a file.
    – x-yuri
    Apr 16 '14 at 11:02




    I'd read that article before you mentioned it. And I understand that the pipes are not seekable, and therefore not all the programs will be able to work with process substitution. The question is why exactly php can't work with process substitution, what prevents it from doing that? perl, ruby, bash and whatnot deal with it just fine. Do you know any other languages with similar problems? Also, I do understand that File.read and <> are different from file_get_contents, but not in the context of the discussion. Considering the topic, they just read a file.
    – x-yuri
    Apr 16 '14 at 11:02













    1














    This is the problem:



    readlink("/dev/fd/63", "pipe:[405116]"..., 4096) = 13
    lstat("/dev/fd/pipe:[405116]", 0x7fff5ea44850) = -1 ENOENT


    Without any good reason (IMHO) php tries to get the real name of the link target. Unfortunately the link target is not part of the file system thus the try to access that name fails and causes this error. The symlink can only be opened as such. I consider this a bug in php. You could use a FIFO instead:



    mkfifo /my/fifo; output_cmd >/my/fifo & php -r ... /my/fifo





    share|improve this answer





















    • But php, opening the file on its own, makes the same system calls and the file is opened successfully. See updated question.
      – x-yuri
      May 4 '13 at 9:38










    • @x-yuri There is neither a "file" nor "on its own". In both cases there is a lstat("/dev/fd/pipe:[405116]", 0x7fff5ea44850) = -1 ENOENT call. Unfortunately the second block ends one line too early. What does the open() call to the file look like? Maybe php can be tricked into opening the link path instead of the "physical" path. But that cannot be forced from the outside.
      – Hauke Laging
      May 4 '13 at 12:56










    • There is no more system calls for php <(echo 12) case. I only forgot to add output of the script itself.
      – x-yuri
      May 5 '13 at 13:51










    • @x-yuri The file is obviously not opened if there is no open() or openat(). The missing error message does not mean that the file was opened successfully.
      – Hauke Laging
      May 5 '13 at 14:02










    • I meant, there is only one call to open(), on the second line of the output (open("/dev/fd/63"...) . Not at the end. So, the file is opened. And the script is run, so the file is opened successfully. Just in case... do note who tries to open the file: php -r '...file_get_contents(...' -- <(echo 12) - the file is opened by the script. php <(echo 12) - the file is opened by php itself and contains the script.
      – x-yuri
      May 5 '13 at 15:23


















    1














    This is the problem:



    readlink("/dev/fd/63", "pipe:[405116]"..., 4096) = 13
    lstat("/dev/fd/pipe:[405116]", 0x7fff5ea44850) = -1 ENOENT


    Without any good reason (IMHO) php tries to get the real name of the link target. Unfortunately the link target is not part of the file system thus the try to access that name fails and causes this error. The symlink can only be opened as such. I consider this a bug in php. You could use a FIFO instead:



    mkfifo /my/fifo; output_cmd >/my/fifo & php -r ... /my/fifo





    share|improve this answer





















    • But php, opening the file on its own, makes the same system calls and the file is opened successfully. See updated question.
      – x-yuri
      May 4 '13 at 9:38










    • @x-yuri There is neither a "file" nor "on its own". In both cases there is a lstat("/dev/fd/pipe:[405116]", 0x7fff5ea44850) = -1 ENOENT call. Unfortunately the second block ends one line too early. What does the open() call to the file look like? Maybe php can be tricked into opening the link path instead of the "physical" path. But that cannot be forced from the outside.
      – Hauke Laging
      May 4 '13 at 12:56










    • There is no more system calls for php <(echo 12) case. I only forgot to add output of the script itself.
      – x-yuri
      May 5 '13 at 13:51










    • @x-yuri The file is obviously not opened if there is no open() or openat(). The missing error message does not mean that the file was opened successfully.
      – Hauke Laging
      May 5 '13 at 14:02










    • I meant, there is only one call to open(), on the second line of the output (open("/dev/fd/63"...) . Not at the end. So, the file is opened. And the script is run, so the file is opened successfully. Just in case... do note who tries to open the file: php -r '...file_get_contents(...' -- <(echo 12) - the file is opened by the script. php <(echo 12) - the file is opened by php itself and contains the script.
      – x-yuri
      May 5 '13 at 15:23
















    1












    1








    1






    This is the problem:



    readlink("/dev/fd/63", "pipe:[405116]"..., 4096) = 13
    lstat("/dev/fd/pipe:[405116]", 0x7fff5ea44850) = -1 ENOENT


    Without any good reason (IMHO) php tries to get the real name of the link target. Unfortunately the link target is not part of the file system thus the try to access that name fails and causes this error. The symlink can only be opened as such. I consider this a bug in php. You could use a FIFO instead:



    mkfifo /my/fifo; output_cmd >/my/fifo & php -r ... /my/fifo





    share|improve this answer












    This is the problem:



    readlink("/dev/fd/63", "pipe:[405116]"..., 4096) = 13
    lstat("/dev/fd/pipe:[405116]", 0x7fff5ea44850) = -1 ENOENT


    Without any good reason (IMHO) php tries to get the real name of the link target. Unfortunately the link target is not part of the file system thus the try to access that name fails and causes this error. The symlink can only be opened as such. I consider this a bug in php. You could use a FIFO instead:



    mkfifo /my/fifo; output_cmd >/my/fifo & php -r ... /my/fifo






    share|improve this answer












    share|improve this answer



    share|improve this answer










    answered May 3 '13 at 23:17









    Hauke Laging

    55.8k1285134




    55.8k1285134












    • But php, opening the file on its own, makes the same system calls and the file is opened successfully. See updated question.
      – x-yuri
      May 4 '13 at 9:38










    • @x-yuri There is neither a "file" nor "on its own". In both cases there is a lstat("/dev/fd/pipe:[405116]", 0x7fff5ea44850) = -1 ENOENT call. Unfortunately the second block ends one line too early. What does the open() call to the file look like? Maybe php can be tricked into opening the link path instead of the "physical" path. But that cannot be forced from the outside.
      – Hauke Laging
      May 4 '13 at 12:56










    • There is no more system calls for php <(echo 12) case. I only forgot to add output of the script itself.
      – x-yuri
      May 5 '13 at 13:51










    • @x-yuri The file is obviously not opened if there is no open() or openat(). The missing error message does not mean that the file was opened successfully.
      – Hauke Laging
      May 5 '13 at 14:02










    • I meant, there is only one call to open(), on the second line of the output (open("/dev/fd/63"...) . Not at the end. So, the file is opened. And the script is run, so the file is opened successfully. Just in case... do note who tries to open the file: php -r '...file_get_contents(...' -- <(echo 12) - the file is opened by the script. php <(echo 12) - the file is opened by php itself and contains the script.
      – x-yuri
      May 5 '13 at 15:23




















    • But php, opening the file on its own, makes the same system calls and the file is opened successfully. See updated question.
      – x-yuri
      May 4 '13 at 9:38










    • @x-yuri There is neither a "file" nor "on its own". In both cases there is a lstat("/dev/fd/pipe:[405116]", 0x7fff5ea44850) = -1 ENOENT call. Unfortunately the second block ends one line too early. What does the open() call to the file look like? Maybe php can be tricked into opening the link path instead of the "physical" path. But that cannot be forced from the outside.
      – Hauke Laging
      May 4 '13 at 12:56










    • There is no more system calls for php <(echo 12) case. I only forgot to add output of the script itself.
      – x-yuri
      May 5 '13 at 13:51










    • @x-yuri The file is obviously not opened if there is no open() or openat(). The missing error message does not mean that the file was opened successfully.
      – Hauke Laging
      May 5 '13 at 14:02










    • I meant, there is only one call to open(), on the second line of the output (open("/dev/fd/63"...) . Not at the end. So, the file is opened. And the script is run, so the file is opened successfully. Just in case... do note who tries to open the file: php -r '...file_get_contents(...' -- <(echo 12) - the file is opened by the script. php <(echo 12) - the file is opened by php itself and contains the script.
      – x-yuri
      May 5 '13 at 15:23


















    But php, opening the file on its own, makes the same system calls and the file is opened successfully. See updated question.
    – x-yuri
    May 4 '13 at 9:38




    But php, opening the file on its own, makes the same system calls and the file is opened successfully. See updated question.
    – x-yuri
    May 4 '13 at 9:38












    @x-yuri There is neither a "file" nor "on its own". In both cases there is a lstat("/dev/fd/pipe:[405116]", 0x7fff5ea44850) = -1 ENOENT call. Unfortunately the second block ends one line too early. What does the open() call to the file look like? Maybe php can be tricked into opening the link path instead of the "physical" path. But that cannot be forced from the outside.
    – Hauke Laging
    May 4 '13 at 12:56




    @x-yuri There is neither a "file" nor "on its own". In both cases there is a lstat("/dev/fd/pipe:[405116]", 0x7fff5ea44850) = -1 ENOENT call. Unfortunately the second block ends one line too early. What does the open() call to the file look like? Maybe php can be tricked into opening the link path instead of the "physical" path. But that cannot be forced from the outside.
    – Hauke Laging
    May 4 '13 at 12:56












    There is no more system calls for php <(echo 12) case. I only forgot to add output of the script itself.
    – x-yuri
    May 5 '13 at 13:51




    There is no more system calls for php <(echo 12) case. I only forgot to add output of the script itself.
    – x-yuri
    May 5 '13 at 13:51












    @x-yuri The file is obviously not opened if there is no open() or openat(). The missing error message does not mean that the file was opened successfully.
    – Hauke Laging
    May 5 '13 at 14:02




    @x-yuri The file is obviously not opened if there is no open() or openat(). The missing error message does not mean that the file was opened successfully.
    – Hauke Laging
    May 5 '13 at 14:02












    I meant, there is only one call to open(), on the second line of the output (open("/dev/fd/63"...) . Not at the end. So, the file is opened. And the script is run, so the file is opened successfully. Just in case... do note who tries to open the file: php -r '...file_get_contents(...' -- <(echo 12) - the file is opened by the script. php <(echo 12) - the file is opened by php itself and contains the script.
    – x-yuri
    May 5 '13 at 15:23






    I meant, there is only one call to open(), on the second line of the output (open("/dev/fd/63"...) . Not at the end. So, the file is opened. And the script is run, so the file is opened successfully. Just in case... do note who tries to open the file: php -r '...file_get_contents(...' -- <(echo 12) - the file is opened by the script. php <(echo 12) - the file is opened by php itself and contains the script.
    – x-yuri
    May 5 '13 at 15:23













    0














    Here's what I ended up using...



    php -r "var_dump(file_get_contents('php://stdin'));" < <(echo this is a win)


    If you're trying to do other stuff with stdin this obviously won't work for you, and this is no different from



    php -r "var_dump(stream_get_contents(STDIN));" < <(echo this is a win)


    which leads me to wonder what it is you were actually trying to do, and why are you stuck on file_get_contents? :)



    Reference - http://php.net/manual/en/wrappers.php.php






    share|improve this answer





















    • I was trying to embed php script into bash script, see my first question.
      – x-yuri
      May 27 '16 at 19:03
















    0














    Here's what I ended up using...



    php -r "var_dump(file_get_contents('php://stdin'));" < <(echo this is a win)


    If you're trying to do other stuff with stdin this obviously won't work for you, and this is no different from



    php -r "var_dump(stream_get_contents(STDIN));" < <(echo this is a win)


    which leads me to wonder what it is you were actually trying to do, and why are you stuck on file_get_contents? :)



    Reference - http://php.net/manual/en/wrappers.php.php






    share|improve this answer





















    • I was trying to embed php script into bash script, see my first question.
      – x-yuri
      May 27 '16 at 19:03














    0












    0








    0






    Here's what I ended up using...



    php -r "var_dump(file_get_contents('php://stdin'));" < <(echo this is a win)


    If you're trying to do other stuff with stdin this obviously won't work for you, and this is no different from



    php -r "var_dump(stream_get_contents(STDIN));" < <(echo this is a win)


    which leads me to wonder what it is you were actually trying to do, and why are you stuck on file_get_contents? :)



    Reference - http://php.net/manual/en/wrappers.php.php






    share|improve this answer












    Here's what I ended up using...



    php -r "var_dump(file_get_contents('php://stdin'));" < <(echo this is a win)


    If you're trying to do other stuff with stdin this obviously won't work for you, and this is no different from



    php -r "var_dump(stream_get_contents(STDIN));" < <(echo this is a win)


    which leads me to wonder what it is you were actually trying to do, and why are you stuck on file_get_contents? :)



    Reference - http://php.net/manual/en/wrappers.php.php







    share|improve this answer












    share|improve this answer



    share|improve this answer










    answered May 26 '16 at 7:58









    user172164

    1




    1












    • I was trying to embed php script into bash script, see my first question.
      – x-yuri
      May 27 '16 at 19:03


















    • I was trying to embed php script into bash script, see my first question.
      – x-yuri
      May 27 '16 at 19:03
















    I was trying to embed php script into bash script, see my first question.
    – x-yuri
    May 27 '16 at 19:03




    I was trying to embed php script into bash script, see my first question.
    – x-yuri
    May 27 '16 at 19:03











    0














    This is an old question but I just figured out the answer so I thought I'd share. Maybe it will help someone.



    You can use the php:// stream wrapper to open the file descriptor instead:



     $fd = $argv[1];
    $handle = fopen(str_replace('/dev/','php://',$fd));


    So instead of opening the /dev/fd/[nn] file descriptor provided by the OS. You'll be opening php://fd/[nn] which will work. I'm not sure why opening the file descriptor fails on some systems but not others.



    This was an old bug and was supposed to have been fixed.






    share|improve this answer


























      0














      This is an old question but I just figured out the answer so I thought I'd share. Maybe it will help someone.



      You can use the php:// stream wrapper to open the file descriptor instead:



       $fd = $argv[1];
      $handle = fopen(str_replace('/dev/','php://',$fd));


      So instead of opening the /dev/fd/[nn] file descriptor provided by the OS. You'll be opening php://fd/[nn] which will work. I'm not sure why opening the file descriptor fails on some systems but not others.



      This was an old bug and was supposed to have been fixed.






      share|improve this answer
























        0












        0








        0






        This is an old question but I just figured out the answer so I thought I'd share. Maybe it will help someone.



        You can use the php:// stream wrapper to open the file descriptor instead:



         $fd = $argv[1];
        $handle = fopen(str_replace('/dev/','php://',$fd));


        So instead of opening the /dev/fd/[nn] file descriptor provided by the OS. You'll be opening php://fd/[nn] which will work. I'm not sure why opening the file descriptor fails on some systems but not others.



        This was an old bug and was supposed to have been fixed.






        share|improve this answer












        This is an old question but I just figured out the answer so I thought I'd share. Maybe it will help someone.



        You can use the php:// stream wrapper to open the file descriptor instead:



         $fd = $argv[1];
        $handle = fopen(str_replace('/dev/','php://',$fd));


        So instead of opening the /dev/fd/[nn] file descriptor provided by the OS. You'll be opening php://fd/[nn] which will work. I'm not sure why opening the file descriptor fails on some systems but not others.



        This was an old bug and was supposed to have been fixed.







        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Dec 19 '18 at 1:45









        Mark Thomson

        1403




        1403






























            draft saved

            draft discarded




















































            Thanks for contributing an answer to Unix & Linux Stack Exchange!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.





            Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


            Please pay close attention to the following guidance:


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f74604%2fhow-to-open-process-substituted-file-from-php%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            Morgemoulin

            Scott Moir

            Souastre