Como explicó @geekosaur, el shell realiza la redirección antes de ejecutar el comando. Cuando escribe esto:
sudo foo >/some/file
Su proceso de shell actual hace una copia de sí mismo que primero intenta abrirse /some/filepara escritura, luego hace que ese descriptor de archivo sea su salida estándar y solo entonces se ejecuta sudo.
Si está permitido (las configuraciones de sudoer a menudo impiden ejecutar shells), puede hacer algo como esto:
sudo bash -c 'foo >/some/file'
Pero encuentro que una buena solución en general es usar en | sudo teelugar de >y en | sudo tee -alugar de >>. Eso es especialmente útil si la redirección es la única razón que necesito sudoen primer lugar; después de todo, ejecutar procesos innecesariamente como root es precisamente lo que sudose creó para evitar. Y correr echocomo root es una tontería.
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
Agregué > /dev/nullal final porque teeenvía su salida tanto al archivo con nombre como a su propia salida estándar, y no necesito verlo en mi terminal. (El teecomando actúa como un conector "T" en una tubería física, que es de donde obtiene su nombre). Y cambié a comillas simples ( '... ') en lugar de dobles ( "... ") para que todo sea literal y no tener que poner una barra invertida delante de la $en $arch. (Sin las comillas o la barra invertida, $archsería reemplazado por el valor del parámetro de shell arch, que probablemente no existe, en cuyo caso $archse reemplaza por nada y simplemente desaparece).
Entonces eso se encarga de escribir en archivos como root usando sudo. Ahora, para una larga digresión sobre las formas de generar texto que contiene una nueva línea en un script de shell. :)
Para BLUF, como dicen, mi solución preferida sería simplemente introducir un documento aquí en el sudo teecomando anterior ; entonces no hay necesidad de cato echoo printfo cualquier otro comando en absoluto. Las comillas simples se han trasladado a la introducción centinela <<'EOF', pero tienen el mismo efecto allí: el cuerpo se trata como texto literal, por lo que $archse deja solo:
sudo tee -a /etc/pacman.conf >/dev/null <<'EOF'
[archlinuxfr]
Server = http://repo.archlinux.fr/$arch
EOF
Pero aunque así es como lo haría, hay alternativas. A continuación, presentamos algunos:
Puede quedarse con uno echopor línea, pero agruparlos todos en una subcapa, por lo que solo tiene que agregar al archivo una vez:
(echo '[archlinuxfr]'
echo 'Server = http://repo.archlinux.fr/$arch'
echo ' ') | sudo tee -a /etc/pacman.conf >/dev/null
Si agrega -ea echo(y está usando un shell que admite esa extensión que no es POSIX), puede incrustar nuevas líneas directamente en la cadena usando \n:
echo -e '[archlinuxfr]\nServer = http://repo.archlinux.fr/$arch\n ' |
sudo tee -a /etc/pacman.conf >/dev/null
Pero como dice arriba, ese no es un comportamiento especificado por POSIX; su shell podría simplemente repetir un literal -eseguido de una cadena con un montón de literales en \nsu lugar. La forma POSIX de hacerlo es usar en printflugar de echo; trata automáticamente su argumento como lo echo -ehace, pero no agrega automáticamente una nueva línea al final, por lo que también debe agregar un extra \nallí:
printf '[archlinuxfr]\nServer = http://repo.archlinux.fr/$arch\n \n' |
sudo tee -a /etc/pacman.conf >/dev/null
Con cualquiera de esas soluciones, lo que el comando obtiene como una cadena de argumento contiene la secuencia de dos caracteres \n, y depende del programa de comando en sí (el código dentro de printfo echo) traducir eso en una nueva línea. En muchos shells modernos, tiene la opción de usar comillas ANSI $'... ', que traducirán secuencias como \nen líneas nuevas literales antes de que el programa de comando vea la cadena. Eso significa que este tipo de cadenas funcionan con cualquier comando que sea, incluyendo a secas -e-menos echo:
echo $'[archlinuxfr]\nServer = http://repo.archlinux.fr/$arch\n ' |
sudo tee -a /etc/pacman.conf >/dev/null
Pero, aunque son más portátiles que echo -e, las citas ANSI siguen siendo una extensión que no es POSIX.
Y nuevamente, si bien esas son todas las opciones, prefiero la tee <<EOFsolución directa anterior.