bash: / dev / stderr: Permiso denegado

Después de actualizar a una nueva versión de lanzamiento, mis scripts bash comienzan a escupir errores:

 bash: /dev/stderr: Permission denied 

en versiones anteriores, Bash reconocería internamente esos nombres de file (que es por lo que esta pregunta no es un duplicado de este ) y haría lo correcto ™ , sin embargo, esto dejó de funcionar ahora. ¿Qué puedo hacer para poder ejecutar mis scripts de nuevo con éxito?

He intentado agregar al usuario que ejecuta la secuencia de commands al grupo tty , pero esto no hace ninguna diferencia (incluso después de cerrar la session y volver a entrar).

Puedo reproducir esto en la línea de command 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 

No creo que esto sea del todo un problema.

En un comentario, dijiste que habías visto este error después de hacer

 sudo su username2 

cuando inicie session como username . Es el su que está desencadenando el problema.

/dev/stdout es un enlace simbólico a /proc/self/fd/1 , que es un enlace simbólico a, por ejemplo, /dev/pts/1 . /dev/pts/1 , que es un pseudoterminal, es propiedad de, y puede escribir, el username ; esa propiedad fue otorgada cuando el username inició session. Cuando 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 sería hacer que username2 un miembro del grupo tty , pero eso daría permiso a username2 para escribir en cualquier tty, lo que probablemente sea indeseable.

Otra solución sería iniciar session en la count username2 lugar de usar su , de modo que /dev/stdout apunte a un pseudoterminal recientemente asignado propiedad de username2 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, aunque el documento bash ( info bash ) en mi sistema dice que /dev/stdout y /dev/stderr se tratan especialmente cuando se usan en las networkingirecciones. Pero incluso si bash no trata esos nombres especialmente, aún deberían actuar como equivalentes para las transmisiones de E / S estándar. (POSIX no menciona /dev/std{in,out,err} , por lo que puede ser difícil argumentar que se trata de un error).

En cuanto a las versiones antiguas de bash, la documentation implica que /dev/stdout et al se tratan especialmente si los files existen o no. La característica se introdujo en bash 2.04, y el file NEWS para esa versión dice:

El código de networkingirección ahora maneja varios nombres de file especialmente: / dev / fd / N, / dev / stdin, / dev / stdout y / dev / stderr, estén o no presentes en el sistema de files.

Pero si examina el código fuente ( networkingir.c ), verá que ese manejo especial está habilitado solo si el símbolo HAVE_DEV_STDIN está definido (esto se determina cuando bash se HAVE_DEV_STDIN 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 less que alguna distribución lo haya parcheado.

Así que otra solución (que no he probado) sería tomar las fonts bash , modificar networkingir.c para hacer que el manejo especial /dev/* incondicional, y usar tu versión reconstruida en lugar de la que viene con tu sistema. Sin embargo, esto es probablemente excesivo.

RESUMEN :

Su sistema operativo, como el mío, no está manejando correctamente la propiedad y los permissions de /dev/stdout y /dev/stderr . bash supuestamente trata estos nombres especialmente en las networkingirecciones, pero de hecho lo hace solo si los files no existen. Eso no importaría si /dev/stdout y /dev/stderr funcionaran correctamente. Este problema solo aparece cuando estás en otra count o haces algo similar; si simplemente inicia session en una count, los permissions son correctos.

Como usuario de Linux desde hace mucho time, recientemente monté un nuevo sistema Ubuntu LTS de 64 bit 12.04 y me desconcertaba por qué mis scripts bash no funcionaban -negación de permiso- y posteriormente encontré este hilo. Pensé que el problema podría deberse a algo en el nuevo sistema operativo.

Al final resulta que estúpidamente usé una herramienta UI para establecer permissions en mi directory /home , y el problema estaba relacionado con la unidad . Para estar seguro, creé un directory temp en /opt y descubrí que mis scripts se ejecutarían perfectamente desde allí. Una vez que arreglé los permissions de /home drive, todo volvió a la normalidad.

Un pequeño misterio resuelto. suspiro

En realidad, la razón de esto es que udev establece específicamente los permissions para 0620 en dispositivos tty y no cambia ni la propiedad ni los permissions, ni debería hacerlo. En mi opinión, esto nos deja en una situación que hace / dev / std * no portátil.

La solución simple es poner "mesg y" en / etc / profile (o cualquier perfil de nivel superior que te guste usar) ya que esto cambia los permissions de tu dispositivo tty a 0622. Realmente no me gusta, pero probablemente sea mejor que cambiar las reglas de udev.