Ich habe ein System, bei dem ich mich nur unter meinem Benutzernamen (myuser) anmelden kann, aber ich muss Befehle als anderer Benutzer (scriptuser) ausführen. Bisher habe ich mir Folgendes ausgedacht, um die Befehle auszuführen, die ich benötige:
ssh -tq myuser@hostname "sudo -u scriptuser bash -c \"ls -al\""
Wenn ich jedoch versuche, einen komplexeren Befehl auszuführen, wie [[ -d "/tmp/Some directory" ]] && rm -rf "/tmp/Some directory"
ich schnell Probleme mit dem Zitieren bekomme. Ich bin nicht sicher, wie ich diesen komplexen Beispielbefehl übergeben könnte bash -c
, wenn \"
bereits die Grenzen des Befehls, den ich übergebe , abgegrenzt sind (und daher weiß ich nicht, wie ich / tmp / Some in Anführungszeichen setzen soll, der ein Leerzeichen enthält.
Gibt es eine allgemeine Lösung, die es mir erlaubt, jeden Befehl weiterzugeben, egal wie komplex / verrückt das Zitieren ist, oder ist dies eine Art von Einschränkung, die ich erreicht habe? Gibt es andere mögliche und vielleicht besser lesbare Lösungen?
Antworten:
Ein Trick, den ich manchmal benutze, ist, base64 zu verwenden, um die Befehle zu kodieren, und es an die andere Site weiterzuleiten:
Dadurch wird das Skript mit Kommas, Backslashes, Anführungszeichen und Variablen in einer sicheren Zeichenfolge codiert und an den anderen Server gesendet. (
-w0
Dies ist erforderlich, um den Zeilenumbruch zu deaktivieren, der standardmäßig in Spalte 76 erfolgt.) Auf der anderen Seite$(base64 -d)
wird das Skript dekodiert und zur Ausführung an die Bash übergeben.Ich habe nie ein Problem damit bekommen, egal wie komplex das Skript war. Behebt das Problem mit der Flucht, weil Sie nichts zu entkommen brauchen. Es wird keine Datei auf dem Remote-Host erstellt, und Sie können mühelos äußerst komplizierte Skripts ausführen.
quelle
ssh user@remotehost "echo `base64 -w0 script.sh` | base64 -d | sudo bash"
base64 script | ssh remotehost 'base64 -d | sudo bash'
wäre genug :)Sehen Sie die
-tt
Option? Lesen Sie dasssh(1)
Handbuch.Eine Sache, die ich oft mache, ist, vim zu benutzen und den
:!cat % | ssh -tt somemachine
Trick anzuwenden .quelle
:!cat % | (command)
kann als:w !(command)
oder getan werden:!(command) < %
.ssh -tt
bewirkt , dass mein ssh nicht beendet wird, nachdem bestimmte Befehle ausgeführt wurden (das Hinzufügenexit
am Ende hilft nicht)Ich denke, die einfachste Lösung liegt in einer Änderung des Kommentars von @ thanasisk.
Erstellen Sie ein Skript, senden Sie
scp
es an den Computer, und führen Sie es dann aus.Habe das Drehbuch
rm
selbst am Start. Die Shell hat die Datei geöffnet, wurde also geladen und kann dann problemlos entfernt werden.Wenn Sie die Dinge in dieser Reihenfolge
rm
erledigen ( erstens, zweitens), wird sie sogar entfernt, wenn sie irgendwann fehlschlägt.quelle
Sie können den
%q
Formatbezeichner mit verwendenprintf
, um die für Sie entstehende Variable zu pflegen:printf -v
schreibt die Ausgabe in eine Variable (in diesem Fall$cmd_str
). Ich denke, dass dies der einfachste Weg ist, es zu tun. Es ist nicht erforderlich, Dateien zu übertragen oder die Befehlszeichenfolge zu codieren (so oft ich den Trick mag).Hier ist ein komplexeres Beispiel, das zeigt, dass es auch für Dinge wie eckige Klammern und kaufmännisches Und funktioniert:
Ich habe es noch nicht getestet,
sudo
aber es sollte so einfach sein wie:Wenn Sie möchten, können Sie einen Schritt überspringen und das Erstellen der Zwischenvariablen vermeiden:
Oder vermeiden Sie es einfach, eine Variable vollständig zu erstellen:
quelle
Hier ist die "richtige" (syntaktische) Methode, um so etwas in bash auszuführen:
Eine ausführliche Beschreibung der Funktionsweise finden Sie unter https://stackoverflow.com/a/21761956/111948
quelle
Ist Ihnen bewusst, dass Sie
sudo
eine Shell verwenden können, in der Sie als ausgewählter Benutzer Befehle ausführen können?quelle
Sie können das Skript auf Ihrem lokalen Computer definieren und es dann
cat
an den Remote-Computer weiterleiten:quelle
sudo -u scriptuser
? Wäre heredoc verwendbar, wenn ich bedenke, dass das Skript Variablen enthalten muss, die an die Maschine weitergeleitet werden sollen?echo "sudo `cat fileForSsh.txt`" | ssh ...
aber ich bekomme weitersudo: sorry, you must have a tty to run sudo
./etc/sudoers
Datei geändert bekommen könnenssh -tq user@host "sudo bash -s" < test.sh
Simpel und einfach.
quelle
Wenn Sie eine ausreichend moderne Bash-Shell verwenden, können Sie Ihre Befehle in eine Funktion einfügen und diese Funktion als Zeichenfolge mit ausgeben
export -p -f function_name
. Das Ergebnis dieser Zeichenfolge kann dann beliebige Befehle enthalten, die nicht unbedingt als root ausgeführt werden müssen.Ein Beispiel mit Pipes aus meiner Antwort auf Unix.SE :
In einem Beispiel, das abgerufen wird, wird die Datei für den angemeldeten Benutzer gespeichert und ein Programm als Root installiert:
Wenn Sie den gesamten Befehl mit ausführen möchten
sudo
, können Sie Folgendes verwenden:quelle
Hier ist meine (nicht wirklich getestete) beschissene Lösung dafür:
Nicht können Sie tun:
Der nächste Schritt besteht darin, ein
betterssh
Skript zu erstellen, das dies bereits tut:quelle
Für diejenigen von Ihnen, die Parameter an das Skript übergeben müssen, sollte dies wie folgt aussehen:
quelle
Erstellen Sie zunächst ein lokales Skript und führen Sie es anschließend mit dem folgenden Befehl aus der Ferne aus:
quelle