【问题标题】:Why can't I write to /dev/stdout, but php://stdout works?为什么我不能写入 /dev/stdout,但 php://stdout 有效?
【发布时间】:2019-10-28 05:25:09
【问题描述】:

我正在尝试使用 PHP 和 Apache(在 Docker 的前台运行)写入标准输出(或标准错误)。

这些作品:

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

更多信息:

  • 我尝试在 php.ini 中设置error_log = /dev/stdout,但它不起作用
  • 我尝试了 Docker 命令 RUN ln -sf /dev/stdout stdout.log,然后在 PHP 中写入 stdout.log,但没有。

再说一遍,php://stdout 做了什么我没有做的事?

【问题讨论】:

  • 可能是更好的答案,但您尝试过STDOUTSTDERR 吗?你不需要打开这些,它们已经打开了,所以写吧。
  • STDOUT/ERR 仅在 CLI afaik 中可用。无论如何,当我尝试它们时它们不起作用。不过还是谢谢。
  • github.com/moby/moby/issues/31243。 “尝试以非 root 用户身份写入 /dev/stdout 时收到权限错误”
  • @ceejayoz 可能是这种情况,尽管我确实尝试过chmod 777 /dev/stdout 无济于事。另外,这如何解释为什么 php://stdout 有效而 /dev/stdout 无效?

标签: php linux apache docker


【解决方案1】:

原因是 Apache 将用户分叉并更改为没有权限写入 /dev/stdout 的特权较低的用户(“apache”用户)。没有简单的方法解决这个问题,所以我最终得到了一个脚本。

该脚本创建一个文件(管道),该文件通过“cat”进程连接,该进程写入标准错误(以 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

现在您可以在 php.ini 中设置error_log = logpipe,所有的 php 错误都会发送到 stderr。

至于为什么php://stdout 有效,我猜是PHP 使用了一个已经被Apache 打开的文件句柄(到/dev/stdout)。

更多详情here.

【讨论】:

    猜你喜欢
    • 2018-09-22
    • 2018-08-12
    • 1970-01-01
    • 1970-01-01
    • 2014-03-06
    • 1970-01-01
    • 2016-09-30
    • 1970-01-01
    相关资源
    最近更新 更多