Führen Sie den Remote-Befehl ssh mit der vollständigen Anmeldeshell aus

48

Ich würde gerne so etwas machen, ssh example.com 'ls'aber per ssh manpage:

Wenn ein Befehl angegeben wird, wird er auf dem Remote-Host anstelle einer Anmeldeshell ausgeführt.

Was also passiert, ist, dass lses seine Ausgabe anzeigt und dann ssh beendet wird.

Was ich nicht herausfinden kann, ist, wie die vollständige Anmeldeshell geöffnet und dann der Befehl in dieser Shell ausgeführt wird. Lassen Sie die Shell geöffnet, nachdem der Befehl ausgeführt wurde. Als hätte ich manuell folgendes gemacht:

  localhost$ ssh example.com 
example.com$ ls
             /folder1 
             /folder2 
example.com$ _

Irgendwelche Ideen?

Matthew
quelle
Dies ist eine ähnliche Frage, superuser.com/questions/261617/… aber keine der Antworten scheint wirklich zu passen, was ich versuche zu tun.
Matthew
Wie wäre es ssh example.com 'ls;bash'?
Andrejs Cainikovs
Sie benötigen das -i auf meinen Systemen, um die zweite Shell interaktiv zu gestalten.
Flexo
Option -t ist die Antwort auf Ihre Frage. Andere Optionen (z. B. Schlüsselbund) sind vorhanden, hängen jedoch von Ihren tatsächlichen Anforderungen ab, die mir nicht klar genug sind.
Hornetbzz
@hornetbzz -t gibt mir Pseudo-tty. Ansonsten ist das Verhalten dasselbe. Ich möchte eine interaktive Shell starten, einen Befehl in dieser Shell ausführen und die Shell geöffnet lassen, nachdem der Befehl ausgeführt wurde.
Matthew

Antworten:

40

Sag bash einfach, dass sie ausgeführt werden soll lsund dann selbst in einer Login-Shell

$ ssh user@host  -t 'bash -l -c "ls;bash"'
fons
quelle
2
Leider scheint dies bei der Verwendung nicht zu funktionieren screen. Ansonsten scheint es das zu tun, was ich versucht habe.
Matthew
31
ssh user@host -t 'ls; exec $SHELL -l'

-tPseudo-Terminal-Zuordnung erzwingen. Dies kann verwendet werden, um beliebige bildschirmbasierte Programme auf einem Remote-Computer auszuführen. Ist etwas richtiger als bash -i.

exec Es wird kein neuer Prozess erstellt.

-lsucht in dieser Reihenfolge nach ~ / .bash_profile, ~ / .bash_login und ~ / .profile und liest und führt Befehle aus ... Ohne diese Funktion können Sie wahrscheinlich keine Skripte / Befehle aus dem Verzeichnis ~ / bin ausführen, da dieser Code from ~ / .profile wird ohne -lflag nicht ausgeführt :

if [ -d "$HOME/bin" ] ; then
    PATH="$HOME/bin:$PATH"
fi
Grawity
quelle
@grawity @Alan Dies könnte als Problemumgehung dienen, aber ich möchte wirklich, dass der Befehl in der Shell ausgeführt wird und nicht nur eine neue Shell geöffnet wird, nachdem der Befehl ausgeführt wurde.
Matthew
+1, -t ist definitiv der richtige Weg, -i zu übergehen, ich habe es nur vergessen.
Flexo
@matthew: Du musst bashdich patchen , um das zuzulassen.
Grawity
@grawity nicht wirklich, siehe meine Antwort unten
fons
@ Matthew, verwenden Sie exec bashoderexec $SHELL
Eugen Konkov
1

In deinem Kommentar zur Antwort von fons sagst du, dass es während der Benutzung nicht funktioniert screen.

Könnten Sie das näher erläutern? Im Quellcode von openssh führt sshd den Befehl durch Aufrufen aus

YOUR_DEFAULT_SHELL -c COMMAND

Wenn Ihre Standard-Shell beispielsweise "" ist screen, funktioniert dies nicht so gut, da screendas -cFlag von "" nur das Flag überschreibt .scrreenrc. Es gibt also wirklich keine Möglichkeit, Befehle an den Bildschirm zu senden, wenn es Ihre Standard-Shell ist. Sie müssen eigentlich screen als Befehl für ssh ausführen, aber mit einer Standard-Shell, die kein screen ist .

Wenn du das versuchst, werden die Dinge wirklich komisch, da screenauch Fenster mit nicht interaktiven Programmen geschlossen werden, also musst du einen ähnlichen Trick wie bei Fons machen, aber eine Ebene tiefer. SO, mit zB / bin / bash (und nicht - Bildschirm) als Standard - Shell So etwas wie:

ssh user@host -t 'screen bash -l -c "ls;bash"'

Um einen tiefen Atemzug zu machen, führen Sie bash -c mit dem Befehl screen aus, wodurch ein neues Fenster geöffnet wird. Wenn dieses Fenster gerade geöffnet würde, würde es enden und der Bildschirm würde sich beenden, also verwenden wir den Trick von fons innerhalb des neuen Bildschirmfensters .

Ich denke, das wird funktionieren, wenn du es überhaupt versucht hast;)

Scott Walls
quelle
Ich denke, das Problem, mit dem ich screenin dieser Situation habe, ist, dass ich es normalerweise exec screen -RRvon meinem lade .profile. Dies bedeutet, dass bash -lversucht wird, einen Bildschirm zu laden, der den Rest davon abwirft. es scheint, dass ich es umgehen kann, indem ich '-l' sowohl in Ihrer als auch in der @ fons-Lösung entferne (Ihre Lösung lässt mich dann drin screen). Es ist aber irgendwie wackelig.
Matthew
0

Mehrere -t-Optionen erzwingen die Zuweisung von tty, auch wenn ssh kein lokales tty hat:

ssh -tt user@host 'bash -l -c "/path/to/command'
panticz.de
quelle