Frage Ssh, führen Sie einen Befehl bei der Anmeldung aus und bleiben Sie dann angemeldet?


Ich habe das mit Expect versucht, aber es hat nicht funktioniert: Es hat die Verbindung am Ende geschlossen.

Können wir ein Skript über ssh ausführen, das sich bei entfernten Rechnern anmeldet, einen Befehl ausführt und nicht trennt?

Also ssh in einer Maschine, CD zu diesem und einem solchen Verzeichnis, und dann einen Befehl ausführen, und bleiben Sie eingeloggt.

Jonathan

(erwarte ich gebraucht)

#!/usr/bin/expect -f
set password [lrange $argv 0 0]
spawn ssh root@marlboro "cd /tmp; ls -altr | tail"
expect "?assword:*"
send -- "$password\r"
send -- "\r"
interact

27
2017-10-29 18:05


Ursprung


Ist es nur ich oder automatisieren Sie die Passwortauthentifizierung auf diese Weise, anstatt Pubkeys oder andere vernünftige Methoden zu verwenden? - grawity


Antworten:


Füge hinzu ein ; /bin/bash bis zum Ende der Befehlszeile auf der Remote-Seite? Das ist:

spawn ssh -t root@marlboro "cd /tmp; ls -altr | tail; /bin/bash -i"

Noch besser, ändere die Bashc-Datei von root wie folgt:

PROMPT_COMMAND="cd /tmp && ls -altr | tail ; unset PROMPT_COMMAND"

:)


24
2017-10-29 18:28



Vielleicht möchten Sie hinzufügen -i zu diesem Bash. - Teddy
Ja, nehme ich an :) - Bill Weiss
Wenn ich das mache, bricht die Tabulatorvervollständigung in der neuen Shell ab (sogar mit "-i") - irgendeine Idee warum / wie zu beheben? - Coderer
Ich habe meine neue Antwort hier getestet, es funktioniert großartig. Ein bisschen grob, aber es funktioniert. - Bill Weiss
Versuchen ssh -t eine Pty zuweisen. - Dennis Williamson


Wenn Sie das in Python machen, pexpect hat ein Beispiel, das fast genau das tut, wonach du fragst:

import pexpect
child = pexpect.spawn ('ftp ftp.openbsd.org')
child.expect ('Name .*: ')
child.sendline ('anonymous')
child.expect ('Password:')
child.sendline ('noah@example.com')
child.expect ('ftp> ')
child.sendline ('ls /pub/OpenBSD/')
child.expect ('ftp> ')
print child.before   # Print the result of the ls command.
child.interact()     # Give control of the child to the user.

Um dies mit ssh anstelle von ftp zu tun, möchten Sie Code ähnlich dem folgenden (die Beispieldateien in Pexpect haben viel mehr Details und Informationen, aber hier sind die Grundlagen):

import pexpect
child = pexpect.spawn ('ssh root@marlboro')
child.expect ('Password:')
child.sendline ('password')
child.expect ('prompt# ')
child.sendline ('cd /tmp')
child.expect ('prompt# ')
child.sendline ('ls -altr | tail')
child.expect ('prompt# ')
print child.before, child.after   # Print the result of the ls command.
child.interact()     # Give control of the child to the user.

Versteh mich nicht falsch, ich LIEBE erwarte (vor allem Autoexpekt), aber Python ist nur so viel einfacher für mich zu grok.


4
2018-05-28 21:53



Ich gehe auch von erwartet zu pexpect über. Python ist jetzt viel allgegenwärtiger. - J. M. Becker


Der wahrscheinlich einfachste und sauberste Weg, um einen Server anzusprechen, eine interaktive Shell zu erstellen und Befehle innerhalb dieser Shell auszuführen, besteht darin, eine benutzerdefinierte RC-Datei für bash zu erstellen.

Geben Sie in Ihrer benutzerdefinierten Bashrc-Datei auf dem Server zuerst die Standarddatei ein und fügen Sie dann Ihre benutzerdefinierten Befehle hinzu, z.

~ / .bashrc_custom:

. ~/.bashrc
cd dir/
workon virtualenvproject

Sie können dann Ihre SSH-Sitzung wie folgt starten:

$ ssh -t server "/bin/bash --rcfile ~/.bashrc_custom -i"

Das -t Option erzwingt eine Pseudo-Tty-Zuweisung, so dass Dinge wie Tab-Vervollständigung funktionieren.

Das --rcfile Die Option gibt an, welche rc-Datei statt der Standard-Rc-Datei geladen werden soll. Wichtig: Sie müssen in der Befehlszeile vor den Ein-Zeichen-Optionen "Doppelstrich-Argumente" eingeben, um erkannt zu werden.

Das -i Argument zu / bin / bash ist dort, um eine interaktive Shell aufzurufen.


3
2018-02-17 12:16



eigentlich nicht. Was kann ich tun, wenn ich für jede Verbindung verschiedene Befehle ausführen möchte? - Eugen Konkov


Wenn jemand Informationen darüber haben möchte, was im Hintergrund passiert, sollten Sie sich das sshd-Handbuch ansehen:

Wenn sich ein Benutzer erfolgreich anmeldet, führt sshd Folgendes aus:

  1. Wenn sich die Anmeldung auf einem TTY befindet und kein Befehl angegeben wurde, werden die letzte Anmeldezeit und / etc / motd gedruckt (sofern in der Konfigurationsdatei oder durch ~ / .hushlogin nicht verhindert; siehe Abschnitt FILES).
  2. Wenn sich die Anmeldung auf einem TTY befindet, wird die Anmeldezeit aufgezeichnet.
  3. Überprüft / etc / nologin und / var / run / nologin; Wenn einer existiert, druckt er den Inhalt und beendet (außer root).
  4. Änderungen, die mit normalen Benutzerberechtigungen ausgeführt werden.
  5. Richtet die Basisumgebung ein.
  6. Liest die Datei ~ / .ssh / environment, falls vorhanden, und Benutzer dürfen ihre Umgebung ändern. Siehe die PermitUserEnvironment-Option in sshd_config (5).
  7. Änderungen im Home-Verzeichnis des Benutzers
  8. Wenn ~ / .ssh / rc existiert, wird es ausgeführt; sonst, wenn / etc / ssh / sshrc existiert, läuft es; Ansonsten wird xauth (1) ausgeführt. Die "rc" -Dateien erhalten das X11-Authentifizierungsprotokoll und den Cookie in der Standardeingabe. Siehe SSHRC, unten.
  9. Führt die Shell des Benutzers aus oder Befehl.

https://www.freebsd.org/cgi/man.cgi?sshd(8)#LOGIN_PROCESS


1
2018-05-08 01:29





Sie sollten es im Allgemeinen vermeiden, ssh auf diese Art und Weise zu benutzen, da es seinen Zweck verfehlt.
Mach ein

ssh-add -l | grep "file_of_your_rsa_priv_key_here"

um zu sehen, ob Ihr Schlüssel im ssh-aktiven Sitzungspool aufgelistet ist oder Sie ihn selbst hinzufügen (mit ssh-add).


0
2018-03-01 21:14