Me dieron acceso a Sudo en una de nuestras cajas RedHat linux de desarrollo, y me parece que a menudo 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 conseguir que esto funcione?
Su comando no funciona porque la redirección la realiza su Shell, que no tiene permiso para escribir en /root/test.out
. La redirección de la salida no esrealizada por Sudo.
Hay múltiples soluciones:
Ejecuta un Shell con Sudo y dale el comando usando la opción -c
:
Sudo sh -c 'ls -hal /root/ > /root/test.out'
Cree un script con sus comandos y ejecute ese script con Sudo:
#!/bin/sh
ls -hal /root/ > /root/test.out
Ejecuta Sudo ls.sh
. Consulte answer de Steve Bennett si no desea crear un archivo temporal.
Inicie un Shell con Sudo -s
y luego ejecute sus comandos:
[[email protected]]$ Sudo -s
[[email protected]]# ls -hal /root/ > /root/test.out
[[email protected]]# ^D
[[email protected]]$
Use Sudo tee
si tiene que escapar mucho al usar la opción -c
):
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 (>>
), use tee -a
o tee --append
(el último es específico para GNU coreutils ).
Gracias a Jd , Adam J. Forster y Johnathan por las soluciones segunda, tercera y cuarta.
Alguien aquí acaba de sugerir sudoing 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 el redireccionamiento a/dev/null es para que se detenga también en la pantalla y se mantenga igual al ejemplo original creado anteriormente.
Un truco que me di cuenta era
Sudo ls -hal /root/ | Sudo dd of=/root/test.out
El problema es que el comandose ejecuta bajo Sudo
, pero el redireccionamiento se ejecuta bajo su usuario. Esto lo hace Shell y hay muy poco que puedas hacer al respecto.
Sudo command > /some/file.log
`-----v-----'`-------v-------'
command redirection
Las formas habituales de eludir esto son:
Envuelve los comandos en una secuencia de comandos que llamas bajo 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 un parámetro con -c
Esto es especialmente útil para comandos compuestos únicos. Por ejemplo:
Sudo bash -c "{ command1 arg; command2 arg; } > /log/file.txt"
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 ventaja (pequeña) de que no es necesario recordar ningún argumento para Sudo
o sh
/bash
Aclarando un poco por qué es preferible la opción de tee
Suponiendo que tenga el permiso adecuado para ejecutar el comando que crea la salida, si canaliza la salida de su comando para realizar un tee, solo necesita elevar los privilegios de tee con Sudo y dirigirlo para escribir (o adjuntar) 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, toma la salida de un comando sin privilegios y escribe en un archivo que normalmente solo se puede escribir por root, 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 fuente es un script en el que no confías por completo, es crucial.
Tenga en cuenta que puede usar la opción -a para añadir el apéndice (como >>
) al archivo de destino en lugar de sobrescribirlo (como >
).
Haz que sudo ejecute un shell, como este:
Sudo sh -c "echo foo > ~root/out"
La forma en que trataría este tema es:
Si necesita escribir/reemplazar el archivo:
echo "some text" | Sudo tee /path/to/file
Si necesita adjuntar al archivo:
echo "some text" | Sudo tee -a /path/to/file
¿Qué hay de escribir un guión?
Nombre de archivo: myscript
#!/bin/sh
/bin/ls -lah /root > /root/test.out
# end script
Luego usa Sudo para ejecutar el script:
Sudo ./myscript
Lo haría de esta manera:
Sudo su -c 'ls -hal /root/ > /root/test.out'
Cada vez que tengo que hacer algo como esto, simplemente me convierto en root:
# Sudo -s
# ls -hal /root/ > /root/test.out
# exit
Probablemente no sea la mejor manera, pero funciona.
No intente vencer a un caballo muerto, pero aquí hay demasiadas respuestas que usan tee
, lo que significa que debe redirigir stdout
a /dev/null
a menos que quiera ver una copia en la pantalla. Una solución más simple es usar cat
de esta manera:
Sudo ls -hal /root/ | Sudo bash -c "cat > /root/test.out"
Observe cómo la redirección se coloca entre comillas para que sea evaluada por un Shell iniciado por Sudo
en lugar del que lo ejecuta.
Esto se basa en la respuesta que implica tee
. Para facilitar las cosas, escribí un pequeño script (lo llamo suwrite
) y lo puse en /usr/local/bin/
con el permiso +x
:
#! /bin/sh
if [ $# = 0 ] ; then
echo "USAGE: <command writing to stdout> | suwrite [-a] <output file 1> ..." >&2
exit 1
fi
for arg in "[email protected]" ; do
if [ ${arg#/dev/} != ${arg} ] ; then
echo "Found dangerous argument ‘$arg’. Will exit."
exit 2
fi
done
Sudo tee "[email protected]" > /dev/null
Como se muestra enUSEen el código, todo lo que tiene que hacer es canalizar la salida a este script seguido del nombre de archivo accesible al superusuario deseado y le solicitará automáticamente su contraseña si es necesario (ya que incluye Sudo
).
echo test | suwrite /root/test.txt
Tenga en cuenta que, dado que se trata de un envoltorio simple para tee
, también aceptará la opción -a
de tee para adjuntar, y también admite la escritura en varios archivos al mismo tiempo.
echo test2 | suwrite -a /root/test.txt
echo test-multi | suwrite /root/test-a.txt /root/test-b.txt
También tiene cierta protección simplista contra la escritura en dispositivos /dev/
, lo cual fue una preocupación mencionada en uno de los comentarios en esta página.
¿Tal vez le han dado acceso a Sudo solo a algunos programas/rutas? Entonces no hay manera de hacer lo que quieres. (A menos que lo hackees de alguna manera)
Si no es el caso, entonces tal vez puedas escribir un script bash:
cat > myscript.sh
#!/bin/sh
ls -hal /root/ > /root/test.out
Prensa ctrl + d :
chmod a+x myscript.sh
Sudo myscript.sh
Espero que te ayude.
Sudo at now
at> echo test > /tmp/test.out
at> <EOT>
job 1 at Thu Sep 21 10:49:00 2017