Come spiegato da @geekosaur, la shell esegue il reindirizzamento prima di eseguire il comando. Quando digiti questo:
sudo foo >/some/file
Il tuo attuale processo di shell crea una copia di se stesso che prima prova ad aprirsi /some/fileper la scrittura, poi se ha successo, fa di quel descrittore di file il suo output standard e solo se ha successo lo esegue sudo. Questo sta fallendo nel primo passaggio.
Se sei autorizzato (le configurazioni di sudoer spesso precludono l'esecuzione di shell), puoi fare qualcosa del genere:
sudo bash -c 'foo >/some/file'
Ma trovo che una buona soluzione in generale sia usare al | sudo teeposto di >e | sudo tee -ainvece di >>. Ciò è particolarmente utile se il reindirizzamento è l'unico motivo di cui ho bisogno sudoin primo luogo; dopotutto, eseguire inutilmente processi come root è esattamente ciò che è sudostato creato per evitare. E correre echocome root è semplicemente stupido.
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/nullalla fine perché teeinvia il suo output sia al file denominato che al proprio output standard, e non ho bisogno di vederlo sul mio terminale. (Il teecomando si comporta come un connettore a "T" in una pipeline fisica, da cui prende il nome.) E sono passato alle virgolette singole ( '... ') invece delle doppie ( "... ") in modo che tutto sia letterale e io non è stato necessario inserire una barra rovesciata davanti a $in $arch. (Senza le virgolette o la barra rovesciata, $archverrebbe sostituito dal valore del parametro della shell arch, che probabilmente non esiste, nel qual caso $archviene sostituito da niente e svanisce.)
Quindi questo si occupa di scrivere sui file come root usando sudo. Ora per una lunga digressione sui modi per produrre testo contenente una nuova riga in uno script di shell. :)
Per BLUF, come si suol dire, la mia soluzione preferita sarebbe semplicemente inserire un here-document nel sudo teecomando precedente ; quindi non c'è bisogno di cator echoor printfo altri comandi. Le virgolette singole sono state spostate nell'introduzione della sentinella <<'EOF', ma lì hanno lo stesso effetto: il corpo viene trattato come testo letterale, quindi $archviene lasciato solo:
sudo tee -a /etc/pacman.conf >/dev/null <<'EOF'
[archlinuxfr]
Server = http://repo.archlinux.fr/$arch
EOF
Ma mentre è così che lo farei, ci sono alternative. Eccone alcuni:
Puoi restare con uno echoper riga, ma raggruppali tutti insieme in una subshell, quindi devi solo aggiungerli al file una volta:
(echo '[archlinuxfr]'
echo 'Server = http://repo.archlinux.fr/$arch'
echo ' ') | sudo tee -a /etc/pacman.conf >/dev/null
Se aggiungi -ea echo(e stai usando una shell che supporta quell'estensione non POSIX), puoi incorporare newline direttamente nella stringa usando \n:
echo -e '[archlinuxfr]\nServer = http://repo.archlinux.fr/$arch\n ' |
sudo tee -a /etc/pacman.conf >/dev/null
Ma come si dice sopra, questo non è un comportamento specificato da POSIX; la tua shell potrebbe semplicemente echeggiare un letterale -eseguito da una stringa con un mucchio di \ns letterali . Il modo POSIX per farlo è usare printfinvece di echo; tratta automaticamente il suo argomento come echo -efa, ma non aggiunge automaticamente una nuova riga alla fine, quindi devi aggiungere un extra anche \nlì:
printf '[archlinuxfr]\nServer = http://repo.archlinux.fr/$arch\n \n' |
sudo tee -a /etc/pacman.conf >/dev/null
Con una di queste soluzioni, ciò che il comando ottiene come stringa di argomento contiene la sequenza di due caratteri \ne spetta al programma di comando stesso (il codice all'interno di printfo echo) tradurlo in una nuova riga. In molte shell moderne, hai la possibilità di utilizzare virgolette ANSI $'... ', che tradurranno sequenze come \nin lettere a capo prima che il programma di comando veda la stringa. Ciò significa che tali stringhe funzionano con qualsiasi comando, incluso il semplice old -e-less echo:
echo $'[archlinuxfr]\nServer = http://repo.archlinux.fr/$arch\n ' |
sudo tee -a /etc/pacman.conf >/dev/null
Ma, sebbene più portabili di echo -e, le virgolette ANSI sono ancora un'estensione non POSIX.
E ancora, sebbene quelle siano tutte opzioni, preferisco la tee <<EOFsoluzione diretta sopra.