Come spiegato da @geekosaur, la shell esegue il reindirizzamento prima di eseguire il comando. Quando si digita questo valore:
sudo foo >/some/file
Il vostro processo shell corrente fa una copia di se stesso che cerca prima di aprire /some/file
per la scrittura, poi fa quel file descrittore suo standard di uscita, e solo allora esegue sudo
.
Se ti è permesso (file di configurazione sudoer spesso precludono corsa conchiglie), si può fare qualcosa di simile:
sudo bash -c 'foo >/some/file'
Ma trovare una buona soluzione, in generale, è quella di utilizzare | sudo tee
invece di >
e | sudo tee -a
invece di >>
. Ciò è particolarmente utile se il reindirizzamento è l'unica ragione per cui ho bisogno di sudo
in primo luogo; dopo tutto, i processi in esecuzione inutilmente come root sono esattamente ciò che sudo
è stato creato per evitare. E l'esecuzione di echo
come root è semplicemente sciocca.
echo '[archlinuxfr]' | sudo tee -a /etc/pacman.conf >/dev/null
echo 'Server = http://repo.archlinux.fr/$arch' | sudo tee -a /etc/pacman.conf >/dev/null
echo ' ' | sudo tee -a /etc/pacman.conf >/dev/null
ho aggiunto > /dev/null
alla fine perché tee
invia il suo output sia il file denominato e un proprio standard di uscita, e non ho bisogno di vedere sul mio terminale. (Il comando tee
si comporta come un connettore "T" in una pipeline fisica, che è dove ottiene il suo nome.) E sono passato a virgolette singole ('
... '
) invece di doppio ("
... "
) tutto è letterale e non ho dovuto inserire una barra rovesciata davanti allo $
in $arch
.
In questo modo è necessario scrivere i file come root utilizzando sudo
. Ora per una lunga digressione sui modi per produrre un testo contenente una nuova riga in uno script di shell. :)
In primo luogo, si può solo gruppo tutti i echo
's insieme in una subshell, in modo da avere a che fare solo il reindirizzamento una volta:
(echo '[archlinuxfr]
echo 'Server = http://repo.archlinux.fr/$arch'
echo ' ') | sudo tee -a /etc/pacman.conf >/dev/null
Oppure utilizzare printf
invece di echo
, in modo da poter newlines incorporare direttamente nella stringa utilizzando \n
:
printf '[archlinuxfr]\nServer = http://repo.archlinux.fr/$arch\n ' |
sudo tee -a /etc/pacman.conf >/dev/null
In bash
, è possibile ottenere lo stesso risultato con echo -e
:
# BASH ONLY - NOT RECOMMENDED
echo -e '[archlinuxfr]\nServer = http://repo.archlinux.fr/$arch\n ' |
sudo tee -a /etc/pacman.conf >/dev/null
Ma la maggior parte delle shell produrrà appena il -e
quando si prova, quindi non è raccomandato.
Con entrambi printf
e echo -e
, quello che il comando si ottengono come una stringa argomento contiene aa backslash seguito da una N letterale ovunque si digita \n
, ed è fino al programma di comando stesso (il codice all'interno printf
o echo
) di tradurre quello in una nuova riga. In molte shell moderne, hai la possibilità di utilizzare le virgolette ANSI $'
... '
, che tradurranno sequenze come \n
in letterale nuove righe prima che il programma di comando visualizzi mai la stringa, il che significa che tali stringhe funzionano con qualsiasi comando:
echo $'[archlinuxfr]\nServer = http://repo.archlinux.fr/$arch\n ' |
sudo tee -a /etc/pacman.conf >/dev/null
Ma, mentre più portabile di echo -e
, citazioni ANSI sono ancora un'estensione non POSIX.
mio modo preferito per farlo sarebbe quello di utilizzare un qui-document e di evitare la necessità di echo
o printf
tutto:
sudo tee -a /etc/pacman.conf >/dev/null <<'EOF'
[archlinuxfr]
Server = http://repo.archlinux.fr/$arch
EOF
possibile duplicato di [Come si usa sudo per reindirizzare l'output in un percorso di I don' t avere il permesso di scrivere su?] (http://stackoverflow.com/questions/82256/how-do-i-use-sudo-to-redirect-output-to-a-locazione-i-dont-have-perm ission-to-wr) –