我正在尝试使用PHP和Apache(在Docker中在前台运行)写到stdout(或stderr)。
这些作品:
file_put_contents( "php://stderr","works" );
file_put_contents( "php://stdout","works" );
$fh = fopen('php://stdout','w'); fwrite($fh, "works");
但是这些不是:
$stdout = fopen ("/dev/stdout","w"); fwrite($stdout, "fails");
$stderr = fopen ("/dev/stderr","w"); fwrite($stderr, "fails");
echo "fd1 exists:" . (file_exists('/proc/self/fd/1') ? 'yes' : 'no');
echo "fd1 writable:" . (is_writable('/proc/self/fd/1') ? 'yes' : 'no');
echo "stdout exists:" . (file_exists('/dev/stdout') ? 'yes' : 'no');
echo "stdout writable:" . (is_writable('/dev/stdout') ? 'yes' : 'no');
file_put_contents( "/proc/self/fd/1", "fails" );
file_put_contents( "/proc/self/fd/2", "fails" );
file_put_contents( "/dev/stdout", "fails" );
fwrite(STDOUT, 'fails');
fwrite(STDERR, 'fails');
/ dev / stdout确实存在,但是不可写。并且fopen('/dev/stdout')
返回FALSE。
fd1 exists:yes
fd1 writable:no
stdout exists:yes
stdout writable:no
更多信息:
error_log = /dev/stdout
,但不起作用RUN ln -sf /dev/stdout stdout.log
,然后用PHP写入stdout.log
,但没有。再次,php:// stdout在做什么,我不这样做?
答案 0 :(得分:1)
原因是Apache派生用户并将其更改为特权较低的用户(“ apache”用户),该用户无权编写/dev/stdout
。解决这个问题没有简单的方法,所以我最后写了一个脚本。
该脚本创建一个文件(管道),该文件通过“ cat”进程连接,该进程写入标准错误(作为根用户):
mkfifo -m 600 logpipe
chown apache:apache logpipe
cat <> logpipe 1>&2 &
CAT=$!
# Start apache
/usr/sbin/httpd -D FOREGROUND
# Kill the cat after apache dies
kill $CAT
现在您可以在php.ini中设置error_log = logpipe
,所有php错误都将发送到stderr。
至于php://stdout
为何起作用,我猜想PHP使用的是Apache /dev/stdout
已打开的文件。
更多详细信息here。