Pregunta ¿Cómo uso sudo para redirigir el resultado a una ubicación en la que no tengo permiso para escribir?


Me han dado acceso a sudo en uno de nuestros cuadros de desarrollo de Linux de RedHat, y parece que a menudo necesito redirigir el resultado a una ubicación a la que normalmente no tengo acceso de escritura.

El problema es que este ejemplo artificial no funciona:

sudo ls -hal /root/ > /root/test.out

Acabo de recibir la respuesta:

-bash: /root/test.out: Permission denied

¿Cómo puedo hacer que esto funcione?


696
2017-09-17 11:44


origen


Respuestas:


Su comando no funciona porque la redirección es realizada por su shell que no tiene permiso para escribir en /root/test.out. La redirección de la salida no es realizado por sudo.

Hay múltiples soluciones:

  • Ejecuta un shell con sudo y dale el comando usando el -c opción:

    sudo sh -c 'ls -hal /root/ > /root/test.out'
    
  • Crea un script con tus comandos y ejecuta ese script con sudo:

    #!/bin/sh
    ls -hal /root/ > /root/test.out
    

    correr sudo ls.sh. Ver Steve Bennett responder si no quieres crear un archivo temporal.

  • Lanza un caparazón con sudo -s luego ejecuta tus comandos:

    [nobody@so]$ sudo -s
    [root@so]# ls -hal /root/ > /root/test.out
    [root@so]# ^D
    [nobody@so]$
    
  • Utilizar sudo tee (si tiene que escapar mucho cuando usa el -c opción):

    sudo ls -hal /root/ | sudo tee /root/test.out > /dev/null
    

    El redireccionamiento a /dev/null es necesario para detener tee desde la salida a la pantalla. A adjuntar en lugar de sobrescribir el archivo de salida (>>), utilizar tee -a o tee --append (el último es específico de GNU coreutils)

Gracias ir a Jd, Adam J. Forster y Johnathan para la segunda, tercera y cuarta soluciones.


975
2017-09-17 11:48



Alguien aquí acaba de sugerir tee de sudoing:

sudo ls -hal /root/ | sudo tee /root/test.out > /dev/null

Esto también podría usarse para redirigir cualquier comando a un directorio al que no tiene acceso. Funciona porque el programa de salida es efectivamente un programa de "eco a un archivo", y la redirección a / dev / null es para detenerlo también dando salida a la pantalla para mantenerlo igual que el ejemplo original de arriba.


80
2017-09-17 12:26



Un truco que descubrí que era

sudo ls -hal /root/ | sudo dd of=/root/test.out

65
2017-11-21 14:24



El problema es que mando se ejecuta bajo sudo, pero el redirección se ejecuta bajo tu usuario. Esto lo hace el caparazón y hay muy poco que puede hacer al respecto.

sudo command > /some/file.log
`-----v-----'`-------v-------'
   command       redirection

Las formas usuales de eludir esto son:

  • Envuelva los comandos en un script que llame bajo sudo.

    Si los comandos y / o el archivo de registro cambian, puede hacer que script toma estos como argumentos. Por ejemplo:

    sudo log_script command /log/file.txt
    
  • Llamar a un shell y pasar la línea de comando como un parámetro con -c

    Esto es especialmente útil para uno de los comandos compuestos. Por ejemplo:

    sudo bash -c "{ command1 arg; command2 arg; } > /log/file.txt"
    

38
2017-09-23 10:10



Otra variación más sobre el tema:

sudo bash <<EOF
ls -hal /root/ > /root/test.out
EOF

O por supuesto:

echo 'ls -hal /root/ > /root/test.out' | sudo bash

Tienen la (pequeña) ventaja de que no necesita recordar ningún argumento para sudo o sh/bash


18
2018-05-13 03:53



Haga sudo ejecutar un shell, como este:

sudo sh -c "echo foo > ~root/out"

15
2017-09-17 11:48



Aclarando un poco sobre por qué la opción de tee es preferible

Suponiendo que tiene el permiso apropiado para ejecutar el comando que crea la salida, si canaliza la salida de su comando a la posición "T", solo necesita elevar los privilegios de la T con sudo y tee directo para escribir (o anexar) al archivo en cuestión.

en el ejemplo dado en la pregunta que significaría:

ls -hal /root/ | sudo tee /root/test.out

para un par de ejemplos más prácticos:

# kill off one source of annoying advertisements
echo 127.0.0.1 ad.doubleclick.net | sudo tee -a /etc/hosts

# configure eth4 to come up on boot, set IP and netmask (centos 6.4)
echo -e "ONBOOT=\"YES\"\nIPADDR=10.42.84.168\nPREFIX=24" | sudo tee -a /etc/sysconfig/network-scripts/ifcfg-eth4

En cada uno de estos ejemplos está tomando el resultado de un comando no privilegiado y escribiendo en un archivo que generalmente solo se puede escribir en la raíz, que es el origen de su pregunta.

Es una buena idea hacerlo de esta manera porque el comando que genera la salida no se ejecuta con privilegios elevados. No parece importar aquí con echo pero cuando el comando de origen es un script en el que no confías por completo, es crucial.

Tenga en cuenta que puede usar la opción -a para juntar el apéndice (como >>) al archivo de destino en lugar de sobrescribirlo (como >)


14
2017-11-02 01:51



¿Qué hay de escribir un guion?

Nombre de archivo: myscript

#!/bin/sh

/bin/ls -lah /root > /root/test.out

# end script

Luego use sudo para ejecutar el script:

sudo ./myscript

5
2017-09-17 11:48



Lo haría de esta manera:

sudo su -c 'ls -hal /root/ > /root/test.out'

4
2018-04-21 12:33



La forma en que abordaría este tema es:

Si necesita escribir / reemplazar el archivo:

echo "some text" | sudo tee /path/to/file

Si necesita anexar al archivo:

echo "some text" | sudo tee -a /path/to/file

4
2018-06-24 19:48