Come faccio a usare sudo per reindirizzare l'output in una posizione non ho il permesso di scrivere?
-
09-06-2019 - |
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?
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 (>>
), usotee -a
otee --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