¿Cómo ejecutar un comando que implica redirigir o canalizar con sudo?


60

Estoy tratando de seguir lo que supongo son las mejores prácticas de uso de sudo en lugar de la cuenta raíz.

Estoy ejecutando una operación simple de archivo concat como:

sudo echo 'clock_hctosys="YES"' >> /etc/conf.d/hwclock

Esto falla a la derecha del ">>" que se está ejecutando como el usuario normal. Agregar sudos adicionales también falla (comportamiento esperado desde la conexión al comando sudo y no al archivo).

El ejemplo es solo eso, pero se ha verificado y probado en la cuenta raíz.

Respuestas:


75

Puede invocar un nuevo shell como root:

sudo sh -c 'echo clock_hctosys=\"YES\" >> /etc/conf.d/hwclock'

También podría simplemente elevar un proceso para escribir en el archivo:

sudo tee -a /etc/conf.d/hwclock > /dev/null << EOF
clock_hctosys="YES"
EOF

8
En general, la segunda opción es más segura porque solo los teecomandos se ejecutan como root, no el comando principal, que podría ser complejo y propenso a un mal comportamiento. (no es el caso de echo)
pabouk

19

Otra opción, igualmente segura, es usar sudoel -iinterruptor para iniciar sesión como root:

$ sudo -i
# echo clock_hctosys=\"YES\" >> /etc/conf.d/hwclock'

Esto sigue las reglas de mejores prácticas ya que la cuenta raíz no está habilitada como tal, pero le permite hacer cosas como root de manera segura. De man sudo:

The -i (simulate initial login) option runs the shell
    specified by the password database entry of the target user
    as a login shell.  This means that login-specific resource
    files such as .profile or .login will be read by the shell.
    If a command is specified, it is passed to the shell for
    execution via the shell's -c option.  If no command is
    specified, an interactive shell is executed. 

Otra alternativa essudo bash
starbeamrainbowlabs

11

Si expresa su comando sin comillas simples, puede ponerlo dentro de comillas simples y ejecutarlo a través de un shell intermedio.

Para ejecutar esto como root:

echo 'clock_hctosys="YES"' >> /etc/conf.d/hwclock

Escriba el comando de una manera diferente que no use ':

echo clock_hctosys=\"YES\" >> /etc/conf.d/hwclock

Luego invoque sudo sh -c …:

sudo sh -c 'echo clock_hctosys=\"YES\" >> /etc/conf.d/hwclock'

Alternativamente, para escribir la salida en un archivo en el que solo la raíz puede escribir, llame sudo tee. Pase la -aopción a teeanexar al archivo de destino; de lo contrario, el archivo se truncará.

echo 'clock_hctosys="YES"' | sudo tee -a /etc/conf.d/hwclock >/dev/null

Para las modificaciones de archivos más complejos, puede llamar sudo sed, sudo ed, sudo perl, ...

Alternativamente, use un editor decente y haga que llame a sudo. En Emacs, abierto /sudo:/etc/conf.d/hwclock. En Vim, llame :w !sudo tee %para escribir en el archivo abierto como root, o use el complemento sudo.vim . O ve desde el extremo del sudo y llama sudoedit /etc/conf.d/hwclock.

O puede ceder al lado oscuro y ejecutar un shell como root.

$ sudo -i
# echo 'clock_hctosys="YES"' >> /etc/conf.d/hwclock

5

El comando falla debido a los permisos en el archivo redirigido a. La redirección ocurre incluso antes de que sudose invoque el comando.

Tendrá que asegurarse de que es la raíz la que realmente abre el archivo para escribir.

La forma más sencilla de hacerlo:

echo 'clock_hctosys="YES"' | sudo tee -a /etc/conf.d/hwclock >/dev/null

Se echopuede ejecutar como usuario normal, ya que solo produce una cadena de texto. Sin teeembargo, la utilidad tendrá que ejecutarse como root y tee -aagregará datos. Redirigimos la salida a /dev/nullporque tee, por defecto, duplicará sus datos de entrada a su salida estándar además de escribir en los archivos indicados.

Con basho cualquier shell que entienda "here-strings":

sudo tee -a /etc/conf.d/hwclock >/dev/null <<<'clock_hctosys="YES"'

Esto es idéntico en efecto a lo anterior. Solo cambia la forma en que producimos la cadena.


Otra forma un poco indirecta de hacerlo:

sudo sh -c 'echo clock_hctosys=\"YES\" >>/etc/conf.d/hwclock'

Aquí, la redirección ocurre dentro de un sh -cshell hijo que se ejecuta como root.


4

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
  • más agradable que shdesde que no hay subshell
  • ddtiene muchas opciones poderosas, por ejemplo, status=progresspara ver el progreso de la transferencia

Funciona porque sudo reenvía stdin al comando.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.