Después de actualizar a una nueva versión de lanzamiento, mis bash
scripts 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/stderr
yls -lL /dev/stdout /dev/stderr
?sudo su username2 -
...echo $BASH_VERSION
Respuestas:
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 losu
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 escribirlousername
; esa propiedad se otorgó alusername
iniciar sesión. Cuando ustedsudo su username2
, la propiedad de/dev/pts/1
no cambia yusername2
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 queecho hello
funciona peroecho hello > /dev/stdout
falla.Una solución alternativa sería formar
username2
un miembro del grupotty
, pero eso daríausername2
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 utilizarlasu
, de modo que/dev/stdout
apunte 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/stdout
y/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/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 elNEWS
archivo 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_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ássu
en otra cuenta o haces algo similar; Si simplemente inicia sesión en una cuenta, los permisos son correctos.fuente
pam_ck_connector.so
como)./proc/self/fd/1
se 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
/home
directorio, y el problema estaba relacionado con la unidad . Para estar seguro, creé untemp
directorio/opt
y descubrí que mis scripts se ejecutarían bien desde allí. Una vez que arreglé los/home
permisos 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