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 随身WiFi网络灯亮但是没有网络,如何解决?
  • ¥15 gdf格式的脑电数据如何处理matlab
  • ¥20 重新写的代码替换了之后运行hbuliderx就这样了
  • ¥100 监控抖音用户作品更新可以微信公众号提醒
  • ¥15 UE5 如何可以不渲染HDRIBackdrop背景
  • ¥70 2048小游戏毕设项目
  • ¥20 mysql架构,按照姓名分表
  • ¥15 MATLAB实现区间[a,b]上的Gauss-Legendre积分
  • ¥15 delphi webbrowser组件网页下拉菜单自动选择问题
  • ¥15 linux驱动,linux应用,多线程