Führen Sie eine Befehlszeile mit einem sudo aus

Führen Sie eine Befehlszeile mit einem sudo aus

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, editaber nicht für den rechten Teil
des>

Sicher, ich könnte vorher Root werden sudo suoder teestattdessen 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 sudodavor einzufügen?

Antwort1

Sie können nicht einfach sudovor 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 Bashfceingebautermö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 sudobeibehalten 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 firstals auch lastdie 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 $0von 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: sudogilt 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; $0funktioniert 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. fchist

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

verwandte Informationen