Wenn Sie versuchen, eine Datei zu ändern, ohne über Schreibrechte zu verfügen, wird folgende Fehlermeldung angezeigt:
> touch /tmp/foo && sudo chown root /tmp/foo
> echo test > /tmp/foo
zsh: permission denied: /tmp/foo
Sudoing hilft nicht weiter, da es den Befehl als root ausführt, aber die Shell das Umleiten von stdout behandelt und die Datei trotzdem öffnet:
> sudo echo test > /tmp/foo
zsh: permission denied: /tmp/foo
Gibt es eine einfache Möglichkeit, stdout zu einer Datei umzuleiten, zu der Sie keine Schreibberechtigung haben, abgesehen davon, dass Sie eine Shell als Root öffnen und die Datei auf diese Weise bearbeiten?
> sudo su
# echo test > /tmp/foo
shell
permissions
io-redirection
sudo
io
Michael Mrozek
quelle
quelle
chown
den Besitzer gewechselt . Es war nur ein BeispielAntworten:
Ja, mit
tee
. Soecho test > /tmp/foo
wird esSie können auch anhängen (
>>
)quelle
echo test | sudo tee /tmp/foo > /dev/null
So ersetzen Sie den Inhalt der Datei durch die Ausgabe von
echo
(wie den>
Shell-Umleitungsoperator).So schreiben Sie in die Datei (am Anfang, obwohl Sie sie
seek
für die Ausgabe an verschiedenen Offsets verwenden können), ohne sie abzuschneiden (wie der1<>
Bourne-Shell-Operator):So hängen Sie
>>
mit GNU an die Datei (wie ) andd
:Siehe auch GNUs
dd
, umconv=excl
zu vermeiden, dass eine vorhandene Datei überladen wird (wieset -o noclobber
in POSIX-Shells) undconv=nocreat
umgekehrt (nur eine vorhandene Datei aktualisieren).quelle
echo test | sudo tee /tmp/foo >/dev/null
die Ausgabe zu verwerfen.dd
ist dafür unzuverlässig, es sei denn, Sie verwenden obskure Nur-GNU-Optioneniflag=fullblock oflag=fullblock
, die die Eleganz dieser Antwort aufheben. Ich bleibe dabeitee
.dd
kann ziemlich gefährlich sein (wenn nicht zu sagen: verheerend), wenn nur ein kleiner Fehler gemacht wurde. Daher würde ich neuen Benutzern dietee
Methode eher empfehlen , um an der sicheren Küste zu sein.dd of=file
alleine (ohnecount
/skip
...) ist es zuverlässig.iflag=fullblock
wird nicht benötigt, da hierdd
bei der Ausgabe das geschrieben wird, was es bei der Eingabe gelesen hat. Es ist egal, ob es nicht volle Blöcke waren.tee
ist wahrscheinlich die beste Wahl, aber je nach Ihrer Situation kann Folgendes ausreichen:quelle
eval
anstelle eines einfachensh -c
; -i, was dein Arbeitsverzeichnis ändert; Ausführen des gesamten Befehls als root, wodurch sich möglicherweise das Verhalten ändert oder ein unnötiges Risiko entsteht. Warum wurde das jemals positiv bewertet?Obwohl ich damit einverstanden bin,
| sudo tee
ist das die kanonische Art und Weise, mit der sed (hier unter der Annahme von GNUsed
) möglicherweise funktioniert:-i
Ändert die vorhandene Datei.1i
bedeutet vor Zeile 1 einfügen .$a
bedeutet nach letzter Zeile anhängen .Oder kopiere auf xclipboard:
quelle
sed -i
die Datei nicht direkt geändert wird. Sie erstellt eine temporäre Datei und benennt sie beim Beenden um. Sie werden also nicht in der Lage sein, so etwas wietail -f ...
in der Originaldatei zu tun und die Ausgabe zu sehen,sed -i ...
während die Pipeline läuft-i creates a new file of same name
oder gibt es etwas kompakteres? Ich denke, ich magin place
, weil es das erklärti
. Die gnu-sed-Manpage nennt es ebenfalls " in place" und die lange Flagge ist "in"--in-place
.Ich habe mir Gedanken über ein ähnliches Problem gemacht und die folgenden Lösungen gefunden:
sudo uncat
Wouncat
ist ein Programm, das die Standardeingabe liest und in die in der Befehlszeile angegebene Datei schreibt, aber ich habe noch nicht geschriebenuncat
.sudocat
die variante davonsudoedit
habe ich noch nicht geschrieben das macht einen sauberersudo cat
odersudo uncat
.oder dieser kleine Trick
sudoedit
mit einem EDITOR, der ein Shell-Skript istDas kann entweder als
|sudo ./uncat file
oder aufgerufen werden| EDITOR=./uncat sudoedit
, hat aber interessante Nebenwirkungen.quelle
cat
nimmt eine Liste von Dateien con Katze inate daher uncat eine Liste von Dateien zu übernehmen sollte un con Katze inate zu. Es müsste Magie verwenden, um zu entscheiden, wie viel in jede Datei eingefügt werden soll. Alternative Namen umfassendog
,to-file
,redirect
.uncat
wenn ich habetee
.tee
hat den kleinen Nachteil, dass es seine Standardeingabe in seine Standardeingabe schreibt - was trivial gemildert wird, indem die Standardeingabe in die Standardeingabe umgeleitet wird/dev/null
. Andere Alternativen sinddd of=/tmp/foo
(in einer anderen Antwort erwähnt), bei der Statusinformationen an stderr geschrieben werden, undcp /dev/stdin /tmp/foo
.Verwenden Sie einen Schwamm aus der moreutils-Packung. Es hat den Vorteil, dass es nicht nach stdout schreibt.
Verwenden Sie die Option -a, um eine Datei anzuhängen, anstatt sie zu überschreiben.
quelle
/dev/null
wenn es ein Problem wäreDer Fehler kommt von der Reihenfolge, in der die Shell die Dinge tut.
Die Umleitung wird behandelt, bevor die Shell überhaupt ausgeführt wird
sudo
, und erfolgt daher mit den Berechtigungen des Benutzers, als dem Sie gerade arbeiten. Da Sie keine Schreibrechte zum Erstellen / Abschneiden des Umleitungsziels haben,permission denied
wird von der Shell eine Fehlermeldung ausgegeben.Die Lösung besteht darin, sicherzustellen, dass die Ausgabedatei unter der Identität erstellt wird, die Sie erhalten
sudo
, z. B. mittee
:quelle