No creo que esto sea completamente un problema bash.
En un comentario, dijo que vio este error después de hacer
sudo su username2
cuando inicie sesión como username
. Es lo su
que está desencadenando el problema.
/dev/stdout
es un enlace simbólico a /proc/self/fd/1
, que es un enlace a, por ejemplo, /dev/pts/1
. /dev/pts/1
, que es un pseudoterminal, es propiedad de y puede escribirlo username
; esa propiedad se otorgó al username
iniciar sesión. Cuando usted sudo su username2
, la propiedad de /dev/pts/1
no cambia y username2
no tiene permiso de escritura.
Yo diría que esto es un error. /dev/stdout
debería ser, en efecto, un alias para el flujo de salida estándar, pero aquí vemos una situación en la que echo hello
funciona pero echo hello > /dev/stdout
falla.
Una solución alternativa sería formar username2
un miembro del grupo tty
, pero eso daría username2
permiso para escribir en cualquier tty, lo que probablemente no sea deseable.
Otra solución alternativa sería iniciar sesión en la username2
cuenta en lugar de utilizarla su
, de modo que /dev/stdout
apunte a un pseudoterminal recientemente asignado propiedad de username2
. Esto podría no ser práctico.
Otra solución sería modificar sus scripts para que no se refieran a /dev/stdout
y /dev/stderr
; por ejemplo, reemplace esto:
echo OUT > /dev/stdout
echo ERR > /dev/stderr
por esto:
echo OUT
echo ERR 1>&2
Veo esto en mi propio sistema, Ubuntu 12.04, con bash 4.2.24, a pesar de que el documento bash ( info bash
) en mi sistema dice eso /dev/stdout
y /dev/stderr
se trata especialmente cuando se usa en redirecciones. Pero incluso si bash no trata esos nombres especialmente, deberían actuar como equivalentes para los flujos de E / S estándar. (POSIX no menciona /dev/std{in,out,err}
, por lo que puede ser difícil argumentar que esto es un error).
Mirando las versiones antiguas de bash, la documentación implica que /dev/stdout
et al son tratados especialmente si los archivos existen o no. La característica se introdujo en bash 2.04, y el NEWS
archivo para esa versión dice:
El código de redirección ahora maneja varios nombres de archivo especialmente: / dev / fd / N, / dev / stdin, / dev / stdout y / dev / stderr, estén o no presentes en el sistema de archivos.
Pero si examina el código fuente ( redir.c
), verá que ese manejo especial está habilitado solo si el símbolo HAVE_DEV_STDIN
está definido (esto se determina cuando bash se construye desde la fuente).
Por lo que puedo decir, ninguna versión lanzada de bash ha hecho que el manejo especial de /dev/stdout
et al sea incondicional, a menos que alguna distribución lo haya parcheado.
Entonces, otra solución (que no he probado) sería tomar las fuentes de bash , modificar redir.c
para hacer que el /dev/*
manejo especial sea incondicional y usar su versión reconstruida en lugar de la que vino con su sistema. Sin embargo, esto probablemente sea exagerado.
RESUMEN :
Su sistema operativo, como el mío, no está manejando la propiedad y los permisos de /dev/stdout
y /dev/stderr
correctamente. supuestamente bash trata estos nombres especialmente en redirecciones, pero de hecho solo lo hace si los archivos no existen. Eso no importa si /dev/stdout
y /dev/stderr
funcionó correctamente. Este problema solo aparece cuando estás su
en otra cuenta o haces algo similar; Si simplemente inicia sesión en una cuenta, los permisos son correctos.
ls -l /dev/stdout /dev/stderr
yls -lL /dev/stdout /dev/stderr
?