Después de actualizar a una nueva versión de lanzamiento, mis bashscripts comienzan a escupir errores:
bash: /dev/stderr: Permission denied
en versiones anteriores, Bash reconocería internamente esos nombres de archivo (razón por la cual esta pregunta no es un duplicado de este ) y haría lo correcto (tm) , sin embargo, esto ha dejado de funcionar ahora. ¿Qué puedo hacer para poder ejecutar mis scripts nuevamente con éxito?
Intenté agregar al usuario que ejecuta el script al grupo tty, pero esto no hace ninguna diferencia (incluso después de cerrar sesión y volver a iniciarla).
Puedo reproducir esto en la línea de comando sin problema:
$ echo test > /dev/stdout
bash: /dev/stdout: Permission denied
$ echo test > /dev/stderr
bash: /dev/stderr: Permission denied
$ ls -l /dev/stdout /dev/stderr
lrwxrwxrwx 1 root root 15 May 13 02:04 /dev/stderr -> /proc/self/fd/2
lrwxrwxrwx 1 root root 15 May 13 02:04 /dev/stdout -> /proc/self/fd/1
$ ls -lL /dev/stdout /dev/stderr
crw--w---- 1 username tty 136, 1 May 13 05:01 /dev/stderr
crw--w---- 1 username tty 136, 1 May 13 05:01 /dev/stdout
$ echo $BASH_VERSION
4.2.24(1)-release
En un sistema anterior (Ubuntu 10.04):
$ echo $BASH_VERSION
4.1.5(1)-release
bash
permissions
stdout
0xC0000022L
fuente
fuente

ls -l /dev/stdout /dev/stderryls -lL /dev/stdout /dev/stderr?sudo su username2 -...echo $BASH_VERSIONRespuestas:
No creo que esto sea completamente un problema bash.
En un comentario, dijo que vio este error después de hacer
cuando inicie sesión como
username. Es losuque está desencadenando el problema./dev/stdoutes 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 escribirlousername; esa propiedad se otorgó alusernameiniciar sesión. Cuando ustedsudo su username2, la propiedad de/dev/pts/1no cambia yusername2no tiene permiso de escritura.Yo diría que esto es un error.
/dev/stdoutdebería ser, en efecto, un alias para el flujo de salida estándar, pero aquí vemos una situación en la queecho hellofunciona peroecho hello > /dev/stdoutfalla.Una solución alternativa sería formar
username2un miembro del grupotty, pero eso daríausername2permiso para escribir en cualquier tty, lo que probablemente no sea deseable.Otra solución alternativa sería iniciar sesión en la
username2cuenta en lugar de utilizarlasu, de modo que/dev/stdoutapunte a un pseudoterminal recientemente asignado propiedad deusername2. Esto podría no ser práctico.Otra solución sería modificar sus scripts para que no se refieran a
/dev/stdouty/dev/stderr; por ejemplo, reemplace esto:por esto:
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/stdouty/dev/stderrse 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/stdoutet al son tratados especialmente si los archivos existen o no. La característica se introdujo en bash 2.04, y elNEWSarchivo para esa versión dice:Pero si examina el código fuente (
redir.c), verá que ese manejo especial está habilitado solo si el símboloHAVE_DEV_STDINestá 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/stdoutet 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.cpara 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/stdouty/dev/stderrcorrectamente. supuestamente bash trata estos nombres especialmente en redirecciones, pero de hecho solo lo hace si los archivos no existen. Eso no importa si/dev/stdouty/dev/stderrfuncionó correctamente. Este problema solo aparece cuando estássuen otra cuenta o haces algo similar; Si simplemente inicia sesión en una cuenta, los permisos son correctos.fuente
pam_ck_connector.socomo)./proc/self/fd/1se están actualizando sus permisos, pero eso no tiene sentido, ya que es un enlace simbólico. También sucede en Fedora, que parece descartar ConsoleKit.En realidad, la razón de esto es que udev establece específicamente los permisos en 0620 en dispositivos tty y su no cambia ni la propiedad ni los permisos, ni debería hacerlo. En mi opinión, esto nos deja en una situación que hace que / dev / std * no sea portátil.
La solución simple es poner "mesg y" en / etc / profile (o cualquier perfil de nivel superior que quiera usar) ya que esto cambia los permisos de su dispositivo tty a 0622. Realmente no me gusta, pero probablemente sea mejor que cambiar las reglas de udev.
fuente
Como usuario de Linux desde hace mucho tiempo, configuré recientemente un nuevo sistema Ubuntu 64 bit 12.04 LTS y estaba desconcertado de por qué mis scripts de bash no funcionaban (permiso denegado) y posteriormente encontré este hilo. Pensé que el problema podría deberse a algo en el nuevo sistema operativo.
Al final resulta que había usado estúpidamente una herramienta de interfaz de usuario para establecer permisos en mi
/homedirectorio, y el problema estaba relacionado con la unidad . Para estar seguro, creé untempdirectorio/opty descubrí que mis scripts se ejecutarían bien desde allí. Una vez que arreglé los/homepermisos de la unidad, todo volvió a la normalidad.Un pequeño misterio resuelto. suspiro
fuente
Esta es una vieja pregunta, pero creo que sigue siendo muy relevante, por lo tanto, aquí hay una solución que encontré que no se menciona aquí.
Me encontré con esta pregunta ya que también he visto problemas en un comando de ejecución de cuenta conmutada 'su' como este en bash:
Como todo lo que intento hacer es redirigir stdout a stderr, lo siguiente logra lo mismo, y funciona incluso en la cuenta conmutada 'su':
fuente