Domanda

Ho dato sudo accesso su una delle nostre sviluppo RedHat linux, e mi sembra di trovarmi molto spesso la necessità di reindirizzare l'output in un luogo che normalmente non hanno accesso in scrittura.

Il problema è che questo esempio artificioso non funziona:

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

Ho appena ricevuto la risposta:

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

Come posso ottenere questo lavoro?

È stato utile?

Soluzione

Il comando non funziona perché il reindirizzamento viene eseguito dalla shell che non hanno il permesso di scrivere /root/test.out.Il reindirizzamento dell'output non è eseguita da sudo.

Ci sono più soluzioni:

  • Eseguire una shell con sudo e dare il comando, utilizzando il -c opzione:

    sudo sh -c 'ls -hal /root/ > /root/test.out'
    
  • Creare uno script con i comandi ed eseguire lo script con sudo:

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

    Eseguire sudo ls.sh.Vedi Steve Bennett risposta se non si desidera creare un file temporaneo.

  • Avviare una shell con sudo -s quindi eseguire i comandi:

    [nobody@so]$ sudo -s
    [root@so]# ls -hal /root/ > /root/test.out
    [root@so]# ^D
    [nobody@so]$
    
  • Utilizzare sudo tee (se dovete scappare un sacco quando si utilizza il -c opzione):

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

    Il redirect /dev/null è necessario per interrompere tee da l'output sullo schermo.Per aggiungere invece di sovrascrivere il file di output (>>), uso tee -a o tee --append (l'ultimo è specifico per GNU coreutils).

Grazie a Jd, Adam J.Forster e Johnathan per il secondo, terzo e quarto soluzioni.

Altri suggerimenti

Qualcuno qui ha solo suggerito sudoing tee:

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

Questo potrebbe anche essere utilizzato per reindirizzare qualsiasi comando, per una directory che non si dispone di accesso.Funziona perché la tee programma è in effetti un "eco di un file di programma", e il rinvio a /dev/null è quello di interrompere anche l'output a schermo per mantenere la stessa come l'originale, in qunto esempio di cui sopra.

Un trucco che ho capito io era

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

Il problema è che il comando viene eseguito sotto sudo, ma il il reindirizzamento viene eseguito sotto il tuo utente.Questo è fatto da shell e c'è ben poco che si può fare su di esso.

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

I soliti modi di bypassare questo sono:

  • Avvolgere i comandi in uno script che si chiama sotto sudo.

    Se i comandi e i/o di file di log delle modifiche, è possibile rendere il script di prendere queste come argomenti.Per esempio:

    sudo log_script command /log/file.txt
    
  • Chiamare una shell e passare alla riga di comando come un parametro con -c

    Questo è particolarmente utile per uno spento comandi composti.Per esempio:

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

Ennesima variazione sul tema:

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

O, naturalmente:

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

Essi hanno il (piccolo) vantaggio che non è necessario ricordare tutti gli argomenti da sudo o sh/bash

Per chiarire un po ' sul perché il tee opzione è preferibile

Supponendo di disporre delle autorizzazioni appropriate per eseguire il comando che crea l'output, se si pipe l'output del comando al tee, è solo bisogno di elevare tee dispone dei privilegi necessari con sudo e diretto tee per scrivere (o aggiungi) per il file in questione.

nell'esempio in questione, che vorrebbe dire:

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

un paio di 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 si sta prendendo l'uscita di un non-privilegiati di comando e scrittura di 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.Non sembra importa qui con echo ma quando la sorgente di comando è uno script che non è completamente fiducia, è fondamentale.

Nota è possibile utilizzare l'opzione-a tee per aggiungere append (come >>) per il file di destinazione, anziché sovrascrivere (come >).

Make sudo eseguire una shell, come questo:

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

Il modo in cui vorrei andare su questo problema sono:

Se avete bisogno di scrivere e 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

Come circa la scrittura di una sceneggiatura?

Nome del file:myscript

#!/bin/sh

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

# end script

Quindi utilizzare il comando sudo per eseguire lo script:

sudo ./myscript

Io farei in questo modo:

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

Ogni volta che devo fare qualcosa di simile a questo ho solo diventare root:

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

Probabilmente non è il modo migliore, ma funziona.

Non voglio battere un cavallo morto, ma ci sono troppe risposte qui che utilizzano tee, il che significa che è necessario reindirizzare stdout per /dev/null a meno che non si desidera vedere una copia sullo schermo.Una soluzione più semplice è quello di utilizzare solo cat come questa:

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

Si noti come il reindirizzamento viene messo all'interno di virgolette in modo che venga valutato da un guscio iniziato da sudo invece di quello in esecuzione.

Questo è in base alla risposta che coinvolgono tee.Per semplificare le cose ho scritto un piccolo script (io la chiamo suwrite) e metterlo in /usr/local/bin/ con +x autorizzazione:

#! /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

Come mostrato nella UTILIZZO nel codice, tutto quello che dovete fare è inviare l'output di questo script seguita dal desiderata superuser accessibile nome di file e automaticamente verrà chiesto la password, se necessario (dato che include sudo).

echo test | suwrite /root/test.txt

Si noti che, poiché questo è un semplice wrapper per tee, sarà , inoltre, accettare tee -a opzione per aggiungere, inoltre, supporta la scrittura a 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 qualche semplicistico di protezione contro la scrittura /dev/ dispositivi che è stata una preoccupazione menzionato in uno dei commenti su questa pagina.

Forse è stato dato sudo accesso solo ad alcuni programmi/percorsi?Quindi non c'è modo di fare quello che vuoi.(a meno che non si hack in qualche modo)

Se non è il caso, allora forse si può scrivere script bash:

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

Premere ctrl + d :

chmod a+x myscript.sh
sudo myscript.sh

La speranza è di aiuto.

sudo at now  
at> echo test > /tmp/test.out  
at> <EOT>  
job 1 at Thu Sep 21 10:49:00 2017  
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top