¿Cómo uso sudo para redirigir la salida a una ubicación en la que no tengo permiso para escribir? [cerrado]
Me dieron acceso sudo en una de nuestras cajas de desarrollo RedHat Linux, y parece que con bastante frecuencia necesito redirigir la salida 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?
Su comando no funciona porque la redirección la realiza su shell, que no tiene permiso para escribir /root/test.out
. La redirección de la salida no la realiza sudo.
Hay múltiples soluciones:
Ejecute un shell con sudo y déle el comando usando la
-c
opción:sudo sh -c 'ls -hal /root/ > /root/test.out'
Cree un script con sus comandos y ejecútelo con sudo:
#!/bin/sh ls -hal /root/ > /root/test.out
Correr
sudo ls.sh
. Consulte la respuesta de Steve Bennett si no desea crear un archivo temporal.Inicie un shell y
sudo -s
luego ejecute sus comandos:[nobody@so]$ sudo -s [root@so]# ls -hal /root/ > /root/test.out [root@so]# ^D [nobody@so]$
Usa
sudo tee
(si tienes que escapar mucho al usar la-c
opción):sudo ls -hal /root/ | sudo tee /root/test.out > /dev/null
La redirección a
/dev/null
es necesaria para evitar que tee salga a la pantalla. Para agregar en lugar de sobrescribir el archivo de salida (>>
), usetee -a
otee --append
(el último es específico de GNU coreutils ).
Gracias a Jd , Adam J. Forster y Johnathan por las soluciones segunda, tercera y cuarta.
Alguien aquí acaba de sugerir sudo tee:
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 tee es efectivamente un programa de "eco a un archivo", y la redirección a /dev/null es para detener su salida a la pantalla para mantenerlo igual que el ejemplo original ideado arriba.
Un truco que descubrí yo mismo fue
sudo ls -hal /root/ | sudo dd of=/root/test.out
El problema es que el comando se ejecuta bajo sudo
, pero la redirección se ejecuta bajo su usuario. Esto lo hace el caparazón y hay muy poco que puedas hacer al respecto.
sudo command > /some/file.log
`-----v-----'`-------v-------'
command redirection
Las formas habituales de evitar esto son:
Envuelva los comandos en un script que llame en sudo.
Si los comandos y/o el archivo de registro cambian, puede hacer que el script los tome como argumentos. Por ejemplo:
sudo log_script command /log/file.txt
Llame a un shell y pase la línea de comando como parámetro con
-c
Esto es especialmente útil para comandos compuestos únicos. Por ejemplo:
sudo bash -c "{ command1 arg; command2 arg; } > /log/file.txt"
Organizar una tubería/subshell con los derechos requeridos (es decir, sudo)
# Read and append to a file cat ./'file1.txt' | sudo tee -a '/log/file.txt' > '/dev/null'; # Store both stdout and stderr streams in a file { command1 arg; command2 arg; } |& sudo tee -a '/log/file.txt' > '/dev/null';
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 es necesario recordar ningún argumento para sudo
o sh
/bash