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?
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.
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.
Era un trucco che ho scoperto
Sudo ls -hal /root/ | Sudo dd of=/root/test.out
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"
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
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 >
).
Fai in modo che Sudo esegua una shell, in questo modo:
Sudo sh -c "echo foo > ~root/out"
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
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
Lo farei in questo modo:
Sudo su -c 'ls -hal /root/ > /root/test.out'
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.
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.
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.
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.
Sudo at now
at> echo test > /tmp/test.out
at> <EOT>
job 1 at Thu Sep 21 10:49:00 2017