Ich versuche, das Hinzufügen einer Repository-Quelle in der pacman.conf-Datei meines Arch zu automatisieren, verwende jedoch den echo
Befehl in meinem Shell-Skript. Es schlägt jedoch folgendermaßen fehl: -
sudo echo "[archlinuxfr]" >> /etc/pacman.conf
sudo echo "Server = http://repo.archlinux.fr/\$arch" >> /etc/pacman.conf
sudo echo " " >> /etc/pacman.conf
-bash: /etc/pacman.conf: Permission denied
Wenn ich manuell Änderungen an /etc/pacman.conf mit vim vornehme, tun Sie dies
sudo vim /etc/pacman.conf
Wenn Sie vim mit beenden :wq
, funktioniert alles einwandfrei und meine pacman.conf wurde manuell aktualisiert, ohne dass Beschwerden über "Berechtigung verweigert" vorliegen.
Warum ist das so? Und wie komme ich sudo echo
zur Arbeit? (Übrigens habe ich es auch versucht, sudo cat
aber das ist fehlgeschlagen, da auch die Berechtigung verweigert wurde.)
Antworten:
Das Problem ist, dass die Umleitung von Ihrer ursprünglichen Shell verarbeitet wird, nicht von
sudo
. Muscheln sind nicht in der Lage, Gedanken zu lesen und wissen nicht, dass diese bestimmte>>
für diesudo
und nicht für sie bestimmt ist.Du brauchst:
sudo)
sudo -s
(so dasssudo
eine Shell verwendet wird, um die angegebene Umleitung zu verarbeiten.)quelle
sudo -s
folgt tun: (1) (2) Echo "# test" >> /etc/pacman.conf funktioniert. Aber ist es möglich, dies in einer einzigen Zeile auszuführen?sudo -s 'echo "# test" >>/etc/pacman.conf'
ist das, was ich dir vermitteln wollte.sudo -s 'echo "# test" >> /etc/pacman.conf' /bin/bash: echo "# test" >> /etc/pacman.conf: No such file or directory
Deshalb habe ich anschließend den 2-stufigen manuellen Prozess ausprobiert.echo 'echo "# test" >> /etc/pacman.conf' | sudo -s
sudo
Deaktivierung der Konfiguration-s
? Visudo?Wie @geekosaur erklärt hat, führt die Shell die Umleitung durch, bevor der Befehl ausgeführt wird. Wenn Sie dies eingeben:
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 wirdsudo
.Wenn Sie erlaubt sind (Sudoer-Konfigurationen schließen häufig das Ausführen von Shells aus), können Sie Folgendes tun:
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 brauchesudo
. Schließlich wurde unnötig Prozesse als Root ausgeführtsudo
, um dies zu vermeiden. Undecho
als Root zu laufen ist einfach albern.Ich habe
> /dev/null
am Ende hinzugefügt, weiltee
die Ausgabe sowohl an die angegebene Datei als auch an die eigene Standardausgabe gesendet wird und ich sie nicht auf meinem Terminal sehen muss. (Dertee
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 ersetztarch
, 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ürcat
oderecho
oderprintf
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: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:Wenn Sie hinzufügen ,
-e
um dieecho
(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
: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 verwendenecho
. Es behandelt sein Argument automatisch wieecho -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
: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 inprintf
oderecho
), 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
-wenigerecho
: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.quelle
sudo bash -c 'foo >/some/file'
funktioniert für mich auf osx :-)cat <<EOF | sudo tee -a /some/file > /dev/null ...
cat
Prozess hinzugefügt haben. :)http://www.innovationsts.com/blog/?p=2758
Da die Anweisungen oben nicht so klar sind, verwende ich die Anweisungen aus diesem Blog-Beitrag. Anhand von Beispielen ist es einfacher zu erkennen, was Sie tun müssen.
Beachten Sie, dass es der zweite Befehl (der Befehl gzip) in der Pipeline ist, der den Fehler verursacht. Hier kommt unsere Technik ins Spiel, Bash mit der Option -c zu verwenden.
In der Ausgabe des Befehls ls können wir sehen, dass die Erstellung der komprimierten Datei erfolgreich war.
Die zweite Methode ähnelt der ersten, da wir eine Befehlszeichenfolge an bash übergeben, dies jedoch in einer Pipeline über sudo.
quelle
quelle
SCHRITT 1 Erstellen Sie eine Funktion in einer Bash-Datei (
write_pacman.sh
)'EOF'
wird keine$arch
Variable interpretieren .STE2- Quell-Bash-Datei
SCHRITT 3 Funktion ausführen
quelle