Pregunta

Me han dado sudo acceso en uno de nuestro desarrollo RedHat linux, y me parece que me encuentro bastante a menudo, la necesidad de redirigir la salida a un lugar que normalmente no tienen acceso de escritura.

El problema es que en este ejemplo inventado 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?

¿Fue útil?

Solución

El comando no funciona porque la redirección se realiza por el shell que no tiene permiso para escribir en el /root/test.out.La redirección de la salida no es realizado por sudo.

Hay varias soluciones:

  • Ejecutar una shell con sudo y dar la orden de que mediante el uso de la -c opción:

    sudo sh -c 'ls -hal /root/ > /root/test.out'
    
  • Crear un script con los comandos y ejecute el script con sudo:

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

    Ejecutar sudo ls.sh.Ver a Steve Bennett respuesta si usted no desea crear un archivo temporal.

  • Lanzar un shell con sudo -s a continuación, ejecute los comandos:

    [nobody@so]$ sudo -s
    [root@so]# ls -hal /root/ > /root/test.out
    [root@so]# ^D
    [nobody@so]$
    
  • Uso sudo tee (si usted tiene que escapar de un lote cuando se utiliza el -c opción):

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

    La redirección a /dev/null es necesario dejar de tee desde la salida a la pantalla.A anexar en lugar de sobrescribir el archivo de salida (>>), el uso de tee -a o tee --append (el último es específico para GNU coreutils).

Gracias a Jd, Adam J.Forster y Johnathan para el segundo, tercer y cuarto soluciones.

Otros consejos

Alguien de aquí tiene apenas sugerido sudoing tee:

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

Esto también podría ser utilizado para redirigir cualquier comando, un directorio que no tienen acceso.Funciona porque el tee de salida del programa es, efectivamente, un "eco a un archivo" del programa, y la redirección a /dev/null es dejar también la salida a la pantalla para mantener el mismo que el original se las ingenió ejemplo anterior.

Un truco que se me ocurrió a mí mismo fue

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

El problema es que la comando se ejecuta bajo sudo, pero el redirección se ejecuta bajo el usuario.Esto se hace por el shell y es muy poco lo que puede hacer al respecto.

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

Las formas usuales de la omisión de este son:

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

    Si los comandos y/o archivo de registro de cambios, puede hacer que el secuencia de comandos de tomar estos como argumentos.Por ejemplo:

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

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

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

Otra variación 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

Que tiene el (pequeño) ventaja de que usted no necesita recordar los argumentos que sudo o sh/bash

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

Asumiendo que usted tiene el permiso adecuado para ejecutar el comando que crea la salida, si el resultado de la canalización de su comando de la camiseta, usted sólo necesita elevar tee privledges con sudo y directa de tee a escribir (o añadir) para el archivo en cuestión.

en el ejemplo dado en la pregunta, que significa:

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

un par más de ejemplos 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 la salida de un no-privilegiado de comandos y escribir en un archivo que es por lo general sólo modificable por 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 que la cuestión aquí con echo pero cuando la fuente de comando es una secuencia de comandos que usted no confía plenamente, es crucial.

Nota puede utilizar la opción-a de la camiseta para anexar append (como >>) para el archivo de destino en lugar de sobrescribir (como >).

Hacer sudo ejecutar un intérprete de comandos, como este:

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

La manera en que yo iría sobre este tema es:

Si usted necesita para escribir/reemplazar el archivo:

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

Si necesita añadir al archivo:

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

Acerca de cómo escribir un guión?

Nombre de archivo:myscript

#!/bin/sh

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

# end script

A continuación, utilice el comando sudo para ejecutar la secuencia de comandos:

sudo ./myscript

Yo lo haría de esta manera:

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

Cada vez que tengo que hacer algo como esto me acaba de convertirse en la raíz:

# sudo -s
# ls -hal /root/ > /root/test.out
# exit

Probablemente no sea la mejor forma, pero funciona.

No me refiero a vencer a un caballo muerto, pero hay demasiadas respuestas aquí que el uso de tee, que significa que usted tiene que redirigir stdout a /dev/null a menos que usted quiere ver una copia en la pantalla.La solución más sencilla es utilizar únicamente cat como este:

sudo ls -hal /root/ | sudo bash -c "cat > /root/test.out"

Observe cómo la redirección se pone dentro de las comillas para que sea evaluado por un shell comenzó por sudo en lugar de la ejecución.

Esto se basa en la respuesta que implican tee.Para facilitar las cosas he escrito un pequeño script (yo lo llamo suwrite) y ponerlo en /usr/local/bin/ con +x permiso:

#! /bin/sh
if [ $# = 0 ] ; then
    echo "USAGE: <command writing to stdout> | suwrite [-a] <output file 1> ..." >&2
    exit 1
fi
for arg in "$@" ; do
    if [ ${arg#/dev/} != ${arg} ] ; then
        echo "Found dangerous argument ‘$arg’. Will exit."
        exit 2
    fi
done
sudo tee "$@" > /dev/null

Como se muestra en la El USO de en el código, todo lo que tienes que hacer es canalizar la salida de este script, seguido por el deseado de superusuario-accesible nombre de archivo y automáticamente se te pedirá tu contraseña si es necesario (ya que incluye sudo).

echo test | suwrite /root/test.txt

Tenga en cuenta que dado que este es un simple contenedor para tee, se aceptará también tee -a opción de anexar, y también soporta la escritura de 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 algunas simplista de protección contra escritura a /dev/ los dispositivos que era una preocupación menciona en uno de los comentarios en esta página.

Tal vez usted ha dado sudo acceso sólo a algunos de los programas/rutas?Entonces no hay manera de hacer lo que quiera.(a menos que se hack de alguna manera)

Si no es el caso, entonces tal vez usted puede escribir un script de bash:

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

Pulse ctrl + d :

chmod a+x myscript.sh
sudo myscript.sh

Espero que sea de ayuda.

sudo at now  
at> echo test > /tmp/test.out  
at> <EOT>  
job 1 at Thu Sep 21 10:49:00 2017  
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top