Wie @geekosaur erklärt hat, führt die Shell die Umleitung durch, bevor der Befehl ausgeführt wird. Wenn Sie dies eingeben:
sudo foo >/some/file
Ihr aktueller Shell-Prozess erstellt eine Kopie von sich selbst, die zuerst /some/file
zum Schreiben geöffnet werden soll , dann den Dateideskriptor zur Standardausgabe macht und erst dann ausgeführt wird sudo
.
Wenn Sie erlaubt sind (Sudoer-Konfigurationen schließen häufig das Ausführen von Shells aus), können Sie Folgendes tun:
sudo bash -c 'foo >/some/file'
Aber ich finde eine gute Lösung im Allgemeinen, | sudo tee
anstelle von >
und | sudo tee -a
anstelle von zu verwenden >>
. Das ist besonders nützlich, wenn die Umleitung der einzige Grund ist, den ich überhaupt brauche sudo
. Schließlich wurde unnötig Prozesse als Root ausgeführt sudo
, um dies zu vermeiden. Und echo
als Root zu laufen ist einfach albern.
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
Ich habe > /dev/null
am Ende hinzugefügt, weil tee
die Ausgabe sowohl an die angegebene Datei als auch an die eigene Standardausgabe gesendet wird und ich sie nicht auf meinem Terminal sehen muss. (Der tee
Befehl verhält sich wie ein „T“ Verbinder in einer physikalischen Pipeline, das ist , wo es seinen Namen hat.) Und ich wechselte zu Apostrophe ( '
... '
) statt Doppelzimmer ( "
... "
) , so dass alles wörtlich und ich musste keinen Backslash vor den $
In setzen $arch
. (Ohne die Anführungszeichen oder den umgekehrten Schrägstrich $arch
würde er durch den Wert des Shell-Parameters ersetzt arch
, der wahrscheinlich nicht vorhanden ist. In diesem Fall wird der $arch
durch nichts ersetzt und verschwindet einfach.)
Das kümmert sich also darum, mit root in Dateien zu schreiben sudo
. Nun zu einem ausführlichen Exkurs über die Ausgabe von Zeilenumbruch enthaltendem Text in einem Shell-Skript. :) :)
Für BLUF wäre es, wie sie sagen, meine bevorzugte Lösung, einfach ein Here-Dokument in den obigen sudo tee
Befehl einzugeben . dann besteht überhaupt keine Notwendigkeit für cat
oder echo
oder printf
oder irgendwelche anderen Befehle. Die einfachen Anführungszeichen wurden in die Sentinel-Einführung verschoben, <<'EOF'
haben dort jedoch den gleichen Effekt: Der Text wird als wörtlicher Text behandelt und $arch
bleibt daher in Ruhe:
sudo tee -a /etc/pacman.conf >/dev/null <<'EOF'
[archlinuxfr]
Server = http://repo.archlinux.fr/$arch
EOF
Aber während ich es so machen würde, gibt es Alternativen. Hier sind ein paar:
Sie können bei einer echo
pro Zeile bleiben , aber alle in einer Unterschale zusammenfassen, sodass Sie die Datei nur einmal anhängen müssen:
(echo '[archlinuxfr]'
echo 'Server = http://repo.archlinux.fr/$arch'
echo ' ') | sudo tee -a /etc/pacman.conf >/dev/null
Wenn Sie hinzufügen , -e
um die echo
(und Sie verwenden eine Shell , dass Träger , die nicht-POSIX - Erweiterung), können Sie neue Zeilen direkt in die Zeichenfolge einbetten kann mit \n
:
# NON-POSIX - NOT RECOMMENDED
echo -e '[archlinuxfr]\nServer = http://repo.archlinux.fr/$arch\n ' |
sudo tee -a /etc/pacman.conf >/dev/null
Wie oben erwähnt, handelt es sich jedoch nicht um ein von POSIX angegebenes Verhalten. Ihre Shell gibt möglicherweise nur ein Literal wieder, -e
gefolgt von einer Zeichenfolge mit einer Reihe von Literalen \n
. Die POSIX-Methode besteht darin, printf
anstelle von zu verwenden echo
. Es behandelt sein Argument automatisch wie echo -e
folgt, fügt jedoch am Ende nicht automatisch eine neue Zeile hinzu, sodass Sie dort auch ein zusätzliches hinzufügen müssen \n
:
printf '[archlinuxfr]\nServer = http://repo.archlinux.fr/$arch\n \n' |
sudo tee -a /etc/pacman.conf >/dev/null
Bei beiden Lösungen enthält das, was der Befehl als Argumentzeichenfolge erhält \n
, die zweistellige Folge , und es liegt am Befehlsprogramm selbst (dem Code in printf
oder echo
), dies in eine neue Zeile zu übersetzen. In vielen modernen Shells haben Sie die Möglichkeit, ANSI-Anführungszeichen $'
... zu verwenden '
, die Sequenzen wie \n
in wörtliche Zeilenumbrüche übersetzen, bevor das Befehlsprogramm die Zeichenfolge jemals sieht. Das bedeutet , dass solche Strings arbeiten mit jedem Befehl auch immer, einschließlich plain old -e
-weniger echo
:
echo $'[archlinuxfr]\nServer = http://repo.archlinux.fr/$arch\n ' |
sudo tee -a /etc/pacman.conf >/dev/null
echo -e
ANSI-Anführungszeichen sind zwar portabler als , aber dennoch eine Nicht-POSIX-Erweiterung.
Und wieder, obwohl dies alles Optionen sind, bevorzuge ich die tee <<EOF
obige direkte Lösung.