gpt4 book ai didi

Docker 中的 PHP - fopen() 或 file_put_contents() 无法写入/proc/1/fd/2 以进行标准输出写入

转载 作者:行者123 更新时间:2023-12-02 18:36:25 40 4
gpt4 key购买 nike

在基于 CentOS7 的 Docker 容器中运行 php-fpm 应用。

因为我使用的是 Docker,所以我必须将所有进程的日志输出写入 PID 1 的输出。这样 Docker 引擎就可以获取日志以供以后处理(因此它们显示在 docker logs 中)。

我可以通过将所有日志写入 /proc/1/fd/2 来实现这一点,在任何应用程序中都不会出现问题。我可以用 nginx 做到这一点,只需执行 echo "test">/proc/1/fd/2 就可以很好地显示 docker logs

但是使用 php 软件我想做同样的事情,写入 /proc/1/fd/2 但是无论我做什么,我似乎都无法获取文件流它。

PHP-FPM 产生许多子进程。因此,我必须显式写入 PID 1 的标准输出!

所以我正在做这样的事情:

$handle = fopen("/proc/1/fd/2", "w");
fwrite($handle, $msg);
fclose($handle);

我刚得到 Warning: fopen(/proc/1/fd/2): failed to open stream: No such file or directory

NOTE: I have also tried this with https://www.php.net/manual/en/function.file-put-contents.php and the same result happens. It's essentially a wrapper for fopen, fwrite, fclose.

我试着把它扔到一个符号链接(symbolic link)上:

bash-4.2$ ls -l /tmp/stdout
lrwxrwxrwx. 1 nginx nginx 12 Apr 10 11:19 /tmp/stdout -> /proc/1/fd/2

然后将方法指向它,如 fopen("/tmp/stdout", "w");

我得到完全相同的错误Warning: fopen(/tmp/stdout): failed to open stream: No such file or directory

这是我需要写入的输出:

bash-4.2$ ls -l /proc/1/fd/2
l-wx------. 1 nginx nginx 64 Apr 10 11:21 /proc/1/fd/2 -> pipe:[3523867]

我可以使用我尝试过的任何其他应用程序(包括 nginx 和 bash)毫无问题地(直接或通过符号链接(symbolic link))写入它。

PHP 进程以拥有输出流的同一用户身份运行

bash-4.2$ ps -ef
UID PID PPID C STIME TTY TIME CMD
nginx 1 0 0 11:21 ? 00:00:00 php-fpm: master process (/etc/php-fpm.conf)
nginx 7 1 0 11:21 ? 00:00:00 php-fpm: pool www
nginx 8 1 0 11:21 ? 00:00:00 php-fpm: pool www
nginx 9 1 0 11:21 ? 00:00:00 php-fpm: pool www
nginx 10 1 0 11:21 ? 00:00:00 php-fpm: pool www
nginx 11 1 0 11:21 ? 00:00:00 php-fpm: pool www
nginx 12 1 0 11:21 ? 00:00:00 php-fpm: pool www

bash-4.2$ ls -l /proc/1/fd/2
l-wx------. 1 nginx nginx 64 Apr 10 11:21 /proc/1/fd/2 -> pipe:[3523867]

我试着给它一些疯狂的权限,他们不接受:

bash-4.2$ chmod 777 /proc/1/fd/2
bash-4.2$ ls -l /proc/1/fd/2
l-wx------. 1 nginx nginx 64 Apr 10 11:21 /proc/1/fd/2 -> pipe:[3523867]

这是 /dev/ 目录,我不能使用它们,因为它们指向 proc/self 而不是 /proc/1:

lrwxrwxrwx. 1 root root   11 Apr 10 11:21 core -> /proc/kcore
lrwxrwxrwx. 1 root root 13 Apr 10 11:21 fd -> /proc/self/fd
crw-rw-rw-. 1 root root 1, 7 Apr 10 11:21 full
drwxrwxrwt. 2 root root 40 Apr 10 11:21 mqueue
crw-rw-rw-. 1 root root 1, 3 Apr 10 11:21 null
lrwxrwxrwx. 1 root root 8 Apr 10 11:21 ptmx -> pts/ptmx
drwxr-xr-x. 2 root root 0 Apr 10 11:21 pts
crw-rw-rw-. 1 root root 1, 8 Apr 10 11:21 random
drwxrwxrwt. 2 root root 40 Apr 10 11:21 shm
lrwxrwxrwx. 1 root root 15 Apr 10 11:21 stderr -> /proc/self/fd/2
lrwxrwxrwx. 1 root root 15 Apr 10 11:21 stdin -> /proc/self/fd/0
lrwxrwxrwx. 1 root root 15 Apr 10 11:21 stdout -> /proc/self/fd/1

I tried changing /dev/fd symlink to point to /proc/1/fd/2 and then trying to write to php://fd/2 and it also didn't work, same error.

最佳答案

php-fpm 在 nginx 用户下运行,我打赌 nginx 用户没有访问 /proc/1/fd/2

要查看 nginx 用户可以走多远,运行:

sudo -u nginx /bin/sh -c 'namei -l /proc/1/fd/2'

我敢打赌它不会达到 2,namei 会告诉您错误发生的位置,修复您的权限。

记录一下,当我在 Debian Linux 系统上运行它时,我得到:

root@x2ratma:~# sudo -u www-data /bin/sh -c 'namei -l /proc/1/fd/2'
f: /proc/1/fd/2
drwxr-xr-x root root /
dr-xr-xr-x root root proc
dr-xr-xr-x root root 1
dr-x------ root root fd
2 - Permission denied

告诉我 www-data 用户没有对/proc/1/fd 文件夹的读取权限。 (一个肮脏的快速修复是:sudo chmod a+rx/proc/1/fd 这意味着 给每个人读取/proc/1/fd 的权限 )

关于Docker 中的 PHP - fopen() 或 file_put_contents() 无法写入/proc/1/fd/2 以进行标准输出写入,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55619229/

40 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com