dpwqicw157673 2019-06-13 15:07
浏览 648
已采纳

为什么我不能写入/ dev / stdout,但php:// stdout有效吗?

I'm trying to write to stdout (or stderr) using PHP with Apache (running in the foreground in Docker).

These works:

file_put_contents( "php://stderr","works" );
file_put_contents( "php://stdout","works" );

$fh = fopen('php://stdout','w'); fwrite($fh, "works");

But these do not:

$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 do exist, but is not writable. also fopen('/dev/stdout') returns FALSE.

fd1 exists:yes
fd1 writable:no
stdout exists:yes
stdout writable:no

More info:

  • I tried setting error_log = /dev/stdout in php.ini, but it doesn't work
  • I tried Docker command RUN ln -sf /dev/stdout stdout.log and then writing to stdout.log in PHP, but nope.

Again, what is php://stdout doing that I don't?

  • 写回答

1条回答 默认 最新

  • dtuzjzs3853 2019-06-14 11:55
    关注

    The reason is that Apache forks and changes user to a less privileged one (the "apache" user) which does not have permission to write /dev/stdout. There is no easy way around this, so I ended up with a script.

    The script creates a file (pipe) which is connected through a 'cat' process which writes to standard error (as root):

    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
    

    Now you can set error_log = logpipe in php.ini and all php errors will be sent to stderr.

    As for why php://stdout works, my guess is that PHP uses an already opened by Apache /dev/stdout.

    More details here.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 素材场景中光线烘焙后灯光失效
  • ¥15 请教一下各位,为什么我这个没有实现模拟点击
  • ¥15 执行 virtuoso 命令后,界面没有,cadence 启动不起来
  • ¥50 comfyui下连接animatediff节点生成视频质量非常差的原因
  • ¥20 有关区间dp的问题求解
  • ¥15 多电路系统共用电源的串扰问题
  • ¥15 slam rangenet++配置
  • ¥15 有没有研究水声通信方面的帮我改俩matlab代码
  • ¥15 ubuntu子系统密码忘记
  • ¥15 保护模式-系统加载-段寄存器