it-swarm-eu.dev

Come faccio a utilizzare Sudo per reindirizzare l'output in una posizione a cui non ho il permesso di scrivere?

Mi è stato concesso l'accesso a Sudo su uno dei nostri box di sviluppo RedHat Linux, e mi sembra di trovarmi abbastanza spesso a dover reindirizzare l'output in una posizione a cui normalmente non ho accesso in scrittura.

Il problema è che questo esempio forzato non funziona:

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

Ho appena ricevuto la risposta:

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

Come posso farlo funzionare?

760
Jonathan

Il tuo comando non funziona perché il reindirizzamento è eseguito da Shell che non ha il permesso di scrivere su /root/test.out. Il reindirizzamento dell'output non è eseguito da Sudo.

Ci sono più soluzioni:

  • Esegui una shell con Sudo e impartisci il comando utilizzando l'opzione -c:

    Sudo sh -c 'ls -hal /root/ > /root/test.out'
    
  • Crea uno script con i tuoi comandi ed esegui quello script con Sudo:

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

    Esegui Sudo ls.sh. Vedi Steve Bennett's answer se non vuoi creare un file temporaneo.

  • Avvia una shell con Sudo -s quindi esegui i tuoi comandi:

    [[email protected]]$ Sudo -s
    [[email protected]]# ls -hal /root/ > /root/test.out
    [[email protected]]# ^D
    [[email protected]]$
    
  • Usa Sudo tee (se devi sfuggire molto quando usi l'opzione -c):

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

    Il reindirizzamento a /dev/null è necessario per fermare tee dall'output allo schermo. Per aggiungere invece di sovrascrivere il file di output (>>), utilizzare tee -a o tee --append (l'ultimo è specifico per GNU coreutils ).

Grazie a Jd , Adam J. Forster e Johnathan per la seconda, terza e quarta soluzione.

1068
Cristian Ciupitu

Qualcuno qui ha appena suggerito sudoing tee:

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

Questo potrebbe anche essere usato per reindirizzare qualsiasi comando, in una directory alla quale non si ha accesso. Funziona perché il programma tee è effettivamente un programma "echo to a file", e il reindirizzamento a/dev/null è di interrompere anche l'output sullo schermo per mantenerlo uguale all'esempio originale originale sopra.

89
Jonathan

Era un trucco che ho scoperto

Sudo ls -hal /root/ | Sudo dd of=/root/test.out
70
rhlee

Il problema è che il comando command viene eseguito in Sudo, ma il redirezione viene eseguito sotto il tuo utente. Questo è fatto dalla Shell e c'è ben poco che puoi fare al riguardo.

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

I soliti modi per aggirare questo sono:

  • Avvolgi i comandi in uno script che chiami in Sudo.

    Se i comandi e/o il file di registro cambiano, puoi fare in modo che lo script Li prenda come argomenti. Per esempio:

    Sudo log_script command /log/file.txt
    
  • Chiama una Shell e passa la riga di comando come parametro con -c

    Ciò è particolarmente utile per i comandi composti singoli Ad esempio:

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

Ancora un'altra variazione sul tema:

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

O ovviamente:

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

Hanno il (piccolo) vantaggio che non è necessario ricordare alcun argomento per Sudo o sh/bash

19
Steve Bennett

Chiarire un po 'sul perché l'opzione tee è preferibile

Supponendo che tu abbia il permesso appropriato per eseguire il comando che crea l'output, se conduci l'output del tuo comando a tee, devi solo elevare i privilegi di tee con Sudo e tee diretto per scrivere (o accodare) al file in questione.

nell'esempio fornito nella domanda ciò significherebbe:

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

per un paio di altri esempi pratici:

# 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

In ognuno di questi esempi stai prendendo l'output di un comando non privilegiato e scrivendo su un file che di solito è scrivibile solo da root, che è l'origine della tua domanda.

È una buona idea farlo in questo modo perché il comando che genera l'output non viene eseguito con privilegi elevati. Qui non sembra avere importanza con echo ma quando il comando source è uno script di cui non ti fidi completamente, è fondamentale.

Nota puoi usare l'opzione -a per tee per aggiungere append (come >>) al file di destinazione piuttosto che sovrascriverlo (come >).

18
jg3

Fai in modo che Sudo esegua una shell, in questo modo:

Sudo sh -c "echo foo > ~root/out"
15
Penfold

Il modo in cui vorrei andare su questo problema è:

Se hai bisogno di scrivere/sostituire il file:

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

Se è necessario aggiungere al file:

echo "some text" | Sudo tee -a /path/to/file
8
Nikola Petkanski

Che ne dici di scrivere una sceneggiatura?

Nome file: myscript

#!/bin/sh

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

# end script

Quindi usa Sudo per eseguire lo script:

Sudo ./myscript
5
Jd

Lo farei in questo modo:

Sudo su -c 'ls -hal /root/ > /root/test.out'
4
fardjad

Ogni volta che devo fare qualcosa del genere divento semplicemente root:

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

Probabilmente non è il modo migliore, ma funziona.

3
Adam J. Forster

Non intendo battere un cavallo morto, ma qui ci sono troppe risposte che usano tee, il che significa che devi reindirizzare stdout a /dev/null a meno che tu non voglia vedere una copia sullo schermo. Una soluzione più semplice è usare semplicemente cat in questo modo:

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

Si noti come il reindirizzamento viene inserito tra virgolette in modo che venga valutato da una shell avviata da Sudo anziché da quella in esecuzione.

3
haridsv

Questo si basa sulla risposta che coinvolge tee. Per semplificare le cose ho scritto un piccolo script (io lo chiamo suwrite) e lo ho inserito in /usr/local/bin/ con l'autorizzazione +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

Come mostrato inUSAGEnel codice, tutto quello che devi fare è canalizzare l'output in questo script seguito dal nome file desiderato accessibile dal superuser e ti chiederà automaticamente la password se necessario (dal momento che include Sudo).

echo test | suwrite /root/test.txt

Si noti che poiché questo è un semplice wrapper per tee, accetta anche l'opzione -a di tee per aggiungere e supporta anche la scrittura su più file allo stesso tempo.

echo test2 | suwrite -a /root/test.txt
echo test-multi | suwrite /root/test-a.txt /root/test-b.txt

Ha anche una protezione semplicistica contro la scrittura su dispositivi /dev/ che era una preoccupazione menzionata in uno dei commenti su questa pagina.

2
jamadagni

Forse ti è stato concesso l'accesso a Sudo solo ad alcuni programmi/percorsi? Quindi non c'è modo di fare quello che vuoi. (a meno che non lo modifichiate in qualche modo)

Se non è il caso, allora forse puoi scrivere script bash:

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

Stampa ctrl + d :

chmod a+x myscript.sh
Sudo myscript.sh

Spero che aiuti.

1
user15453
Sudo at now  
at> echo test > /tmp/test.out  
at> <EOT>  
job 1 at Thu Sep 21 10:49:00 2017  
0
user8648126