Estoy tratando de escribir en stdout (o stderr) usando PHP con Apache (ejecutándose en primer plano en Docker).
estos trabajos:
file_put_contents( "php://stderr","works" ); file_put_contents( "php://stdout","works" ); $fh = fopen('php://stdout','w'); fwrite($fh, "works");Pero estos no:
$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 existe, pero no se puede escribir. también fopen('/dev/stdout') devuelve FALSO.
fd1 exists:yes fd1 writable:no stdout exists:yes stdout writable:noMás información:
error_log = /dev/stdout en php.ini, pero no funcionaRUN ln -sf /dev/stdout stdout.log y luego escribí en stdout.log en PHP, pero no.De nuevo, ¿qué está haciendo php://stdout que yo no?
La razón es que Apache se bifurca y cambia de usuario a uno con menos privilegios (el usuario "apache") que no tiene permiso para escribir /dev/stdout . No hay una manera fácil de evitar esto, así que terminé con un guión.
El script crea un archivo (tubería) que se conecta a través de un proceso 'cat' que escribe en el error estándar (como raíz):
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 Ahora puede configurar error_log = logpipe en php.ini y todos los errores de php se enviarán a stderr.
En cuanto a por qué funciona php://stdout , supongo que PHP usa un identificador de archivo (para /dev/stdout ) que ya está abierto por Apache.
Más detallesaquí .