¿Cómo resolver el "permiso denegado" cuando se usa sudo con redirección en Bash?

138

Cuando uso sudo para permitir ediciones en archivos, regularmente recibo 'permiso denegado'.

Por ejemplo, mi mouse está nervioso y lento, por lo que quiero desactivar el sondeo:

sudo echo "options drm_kms_helper poll=N">/etc/modprobe.d/local.conf

Se me solicita una contraseña y luego obtengo:

bash: /etc/modprobe.d/local.conf: Permission denied

Así que intenté hacer un cambio temporal para deshabilitar el sondeo usando:

sudo echo N> /sys/module/drm_kms_helper/parameters/poll

Una vez más, el sistema respondió con:

bash: /sys/module/drm_kms_helper/parameters/poll: Permission denied

¿Algunas ideas?

Jack
fuente

Respuestas:

158

La redirección de salida (a través del >operador) se realiza por el shell, no por eco . Tienes que iniciar sesión como root

sudo -i

Entonces puedes usar la redirección

echo N> /sys/module/drm_kms_helper/parameters/poll

De lo contrario, puede ejecutar bash string con sudo

sudo bash -c "echo N> /sys/module/drm_kms_helper/parameters/poll"
shantanu
fuente
1
¿No puedes ejecutar echo con sudo? lo que sobre el resultado que obtuve:saji@laptop:~$ sudo echo "Hi" [sudo] password for saji: Hi
saji89
puede escribir en el archivo, repetir "algo"> algún lugar. Está usando tubería ... Ese es el problema.
shantanu
44
Ok, si ese es el caso, actualice su respuesta para reflejar que el eco en ejecución es un problema solo en ese caso.
saji89
No puede simplemente ejecutar el shell incorporado echocomo sudo, a menos que haga algo como sudo bash -c 'echo …'; sin embargo, los sistemas POSIX generalmente proporcionan un echocomando externo como /bin/echoen OS X, que sudo puede ejecutar sin rigamarole. Por lo tanto, el echocomando que usualmente ejecuta y el echocomando que ejecuta con sudo son probablemente dos comandos diferentes, pero similares.
kojiro
Si ese es el caso, ¿por qué las respuestas a esta pregunta sugieren eco? askubuntu.com/questions/840431/…
Harsha
75

La redirección de salida la realiza el shell desde el que se ha invocado el comando . Entonces, dividiendo todo en bits, aquí está lo que está sucediendo *:

  • invoca shell sudo echo "options drm_kms_helper poll=N", que ejecuta el sudocomando con la echo "options drm_kms_helper poll=N"línea de comando

  • sudo solicita una contraseña, abre el shell de superusuario e invoca echo "options drm_kms_helper poll=N", que ejecuta el echocomando pasándolo"options drm_kms_helper poll=N"

  • echo, ejecutándose con rootprivilegios, imprime la cadena a su salida estándar.

  • echoel comando termina, el shell del superusuario sale, sudotermina

  • el shell desde el que se ha invocado el comando recopila el resultado e intenta redirigirlo /etc/modprobe.d/local.conf, que solo se puede escribir por root. Se obtiene el error "permiso denegado".

Para conocer las formas de solucionar esto, consulte la respuesta @shantanu.


(*) - mientras que la secuencia anterior ayuda a comprender por qué falla el comando, en realidad las cosas suceden algo fuera de orden: el shell original nota la redirección e intenta abrir el archivo para escribir antes de invocar el sudo ...comando. Cuando se abre el archivo, el shell ni siquiera invoca el comando que se suponía que debía escribir en el archivo (gracias a @PanosRontogiannis por señalar esto).

Aquí hay una prueba rápida:

$ touch ./onlyroot.txt
$ sudo chown root:root ./onlyroot.txt
$ sudo bash -c "whoami | tee who.txt" > onlyroot.txt
bash: onlyroot.txt: Permission denied

En la prueba anterior, whoami | tee who.txtiba a crear un archivo llamado que who.txtcontiene la palabra "raíz". Sin embargo, cuando la redirección de salida falla en el shell de llamada, también falta el archivo "who.txt" porque no se invocó el comando.

Sergey
fuente
Lo más probable es que el shell se bifurque e intente abrir /etc/modprobe.d/local.conf antes de intentar 'exec' sudo, lo que significa que los primeros 4 pasos que describe nunca ocurren porque el archivo no se puede abrir.
Panos Rontogiannis
1
@PanosRontogiannis: gracias, he actualizado la respuesta
Sergey
60

Agregando a la respuesta de Shantanu:

... O podrías usar un teecomando como este:

sudo tee /sys/module/drm_kms_helper/parameters/poll <<<10

o si es la salida de un comando:

echo 10 | sudo tee /sys/module/drm_kms_helper/parameters/poll
Intitulado
fuente
3
El inicio de sesión de +1 como root es una mala idea para el trabajo manual y una muy mala idea para las tareas con guiones.
l0b0
2
Además, sudo tee /sys/module/drm_kms_helper/parameters/poll > /dev/nullsi no desea que se imprima stdouttambién.
Fabian Tamp
16

Un enfoque que no he visto mencionado aquí es simplemente ejecutar toda la línea de comandos en su propio shell. La página de sudomanual en sí misma da un ejemplo de este enfoque:

Para hacer una lista de uso de los directorios en la partición / home. Tenga en cuenta que esto ejecuta los comandos en un sub-shell para que el CD y la redirección de archivos funcionen.

$ sudo sh -c "cd /home ; du -s * | sort -rn > USAGE"
kojiro
fuente
Wow gracias. una solución simple
Resiliencia
4

Otra opción es usar un archivo temporal. Esto es útil en un script bash.

temp=$(mktemp)
echo "Hello, world!" > $temp
sudo cp $temp /etc/wherever
usuario545424
fuente
3

sudo dd of=

Para agregar como quieras:

echo inbytes | sudo dd of=outfile oflag=append conv=notrunc

o para recrear el archivo desde cero:

echo inbytes | sudo dd of=outfile

Ventajas:

  • mejor que teedesde que no hay /dev/nullredirección
  • mejor que shdesde que no hay una subshell explícita (pero implícita para la redirección)
  • ddtiene muchas opciones poderosas, por ejemplo, status=progresspara ver el progreso de la transferencia

Funciona porque sudo reenvía stdin al comando.

Ciro Santilli 新疆 改造 中心 法轮功 六四 事件
fuente
1
Esto es bueno. Pensamos dden cómo sobrescribimos nuestros sistemas de archivos que alguna vez fueron excelentes, y no nos damos cuenta de que también es para tareas mundanas, y que otros comandos como root también causan un gran daño si se usan en los archivos / dispositivos incorrectos. Al igualsudo tee , sudo ddserá, por supuesto, también trabajar con aquí cuerdas , por ejemplo, sudo dd of=outfile <<<'hello world'. [Gracias por editar. NB con sh -c 'cmd', shes un subproceso que es un shell, pero en realidad no es un subshell, excepto en el sentido de que todos los comandos externos comienzan como uno.]
Eliah Kagan