Wenn ich beispielsweise eine Datei erstellen und Text in einer Zeile eingeben möchte, kann ich die Ausgabe mithilfe des >
Operators in eine Datei umleiten:
echo "something" > /path/foobar
aber wenn ich keinen Zugriff auf den Ordner habe /path/
und Sudo-Berechtigungen benötige, wie kann ich denselben Befehl als normaler Benutzer mit Sudo-Rechten ausführen?
Ich habe es versucht
sudo echo "something" > /path/foobar
aber das funktioniert nicht, weil das sudo nur für den, edit
aber nicht für den rechten Teil
des>
Sicher, ich könnte vorher Root werden sudo su
oder tee
stattdessen Folgendes verwenden:
echo "something" | sudo tee /path/foobar
Aber ich würde gerne eine Lösung finden, bei der ich mit der letzten Zeile als Ersatz arbeiten kann über
sudo !!
Gibt es keine Möglichkeit, die letzte Zeile „wiederzuverwenden“ und sie einfach sudo
davor einzufügen?
Antwort1
Sie können nicht einfach sudo
vor einen Shell-Befehl kleben, Sie müssen eine Shell aufrufen, um diesen Befehl erneut auszuwerten (Dinge wie Variablen erweitern, Dateien für Umleitungsoperatoren öffnen usw.). Das ist also
sudo bash -c !!
außer dass dies nicht ganz funktioniert, weil !!
der Text des vorherigen Befehls, Sonderzeichen und alles andere, interpoliert wird. Sie müssen den Text des Befehls als Zeichenfolge abrufen und diese als Argument an übergeben sh
. Glücklicherweise bietet Bashfc
eingebautermöglicht Ihnen das¹.
sudo bash -c "$(fc -ln -1)"
Oder um sicherzugehen, dass die gleiche Bash-Version aufgerufen wird, die aktuell ausgeführt wird:
sudo "$BASH" -c "$(fc -ln -1)"
Beachten Sie, dass der Befehl, da er in einem separaten Shell-Prozess ausgeführt wird, Umgebungsvariablen erbt (nur die, die sudo
beibehalten werden, wohlgemerkt), aber keine internen Shell-Variablen. Shell-Optionen (z. B. kshglob
) und andere Einstellungen werden ebenfalls mit der Standardeinstellung gestartet.
Derselbe Befehl² funktioniert in zsh und ksh, allerdings erfordert ATT ksh93, dass sowohl die first
als auch last
die Zahl an ³ übergeben werden fc
(was auch in bash, zsh und pdksh/mksh funktioniert):
sudo zsh -c "$(fc -ln -1)"
sudo ksh -c "$(fc -ln -1 -1)"
sudo "$0" -c "$(fc -ln -1 -1)"
Die Verwendung $0
von zur Bezeichnung der ausführbaren Datei der laufenden Shell funktioniert nur, wenn die Shell über $PATH aufgerufen wurde und sich $PATH nicht geändert hat, oder über einen absoluten Pfad.
Hier ist eine andere Methode in zsh, die etwas klarer, aber länger ist:
sudo zsh -c $history[$[HISTCMD-1]]
Ein letztes Wort der Warnung: sudo
gilt für potenziell gefährliche Befehle. Machen Sie es nicht zu einfach, sie zu verwenden!
¹ Am Anfang gibt es ein paar zusätzliche Leerzeichen und die Befehlsersetzung entfernt am Ende Zeilenumbrüche, aber die Syntax der Shell kümmert sich nicht darum.
² Ich glaube nicht, dass zsh oder ksh irgendetwas wie bashs haben $BASH
; $0
funktioniert nur, wenn es ein absoluter Pfad ist oder wenn es keinen Schrägstrich enthält und der Befehlssuchpfad sich nicht geändert hat.
³ ist ein Alias für in ATT ksh, aber das ist genauso gut. fc
hist
Antwort2
Wenn Sie den gleichen Befehl wiederholen möchten mitsudo!!nachdem Sie einen Befehl wie diesen ausgeführt haben:
echo "something">/path/file
Anschließend verwenden Sie die globale Ersetzungssyntax, um den Befehl erneut aufzurufen:
!!:gs/>/|sudo tee -a /
Verwenden Sie ein Leerzeichen nach dem-AParameter.
Dies ist das Äquivalent zusudo!!hilft Ihnen aber, die Sudo-Einschränkungen für < und > zu umgehen. Denn Sudo erlaubt die Verwendung von [<, >] nicht.
Um Sudo-Einschränkungen für Weiterleitungen generell zu umgehen, können Sie es wie folgt verwenden:
echo "something" | sudo tee myfile
Mit dem Befehl tee können Sie von der Standardeingabe lesen und in die Standardausgabe und in Dateien schreiben
Wenn Sie den Befehl wiederholen und einen Text an die Datei anhängen möchten, hat der Befehl tee die-AOption zum Anhängen. Sie können den Befehl also mit
sudo !!
und der Text wird in die Datei angehängt
Beispiel:
echo "something" | sudo tee -a /path/file
sudo !!
Antwort3
Es scheint so einfach zu sein wie sudo sh -c "!!"
:
$ cd /
$ echo hello > foo
bash: foo: Permission denied
$ sudo sh -c "!!"
sudo sh -c "echo hello > foo"
$ ls -l foo
-rw-r--r-- 1 root root 6 Jun 20 16:21 foo