es gibt bestimmt einen Weg, aber ich brauche etwas Starthilfe zur
Lösung:
Ich melde mich momentan von einem Ubuntu-Rechner an einem anderen Gerät
per Terminal / ssh an, gebe mein Kennwort ein, tippe dann ein paar
Befehle und bekomme Daten, die ich mir kopiere und auf meinem Rechner
weiterverwende.
Nun würde ich das gerne automatisieren, also z.B. als Cron-Job ein
Script aufrufen, das meine Sachen tippt (immer gleich, kann man in eine
Datei tun) und die Ausgaben in eine Datei tut, also prinzipiell
ssh user@irgendwo << eingaben.txt > Ergebnis.txt
aber ich scheitere schon am Passwort. Auch wenn es in der Eingabedatei
ist, wird es nicht "getippt" - wie macht man sowas / geht das?
Also ich habe gedacht ich fange klein an mit einer Datei "pw.txt" und
rufe auf
ssh user@host < pw.txt
aber ich bekomme als Ergebnis:
Pseudo-terminal will not be allocated because stdin is not a terminal.
und die Eingabe ist nicht umgeleitet..
Zertifikate, von mir aus mit dem Private-Key ohne Passwort, sind die
beste Lösung.
Wenn das aus irgendeinem Grund nicht gehen sollte, gibt es noch sshpass
als Notlösung.
Martin schrieb:> es gibt bestimmt einen Weg, aber ich brauche etwas Starthilfe zur> Lösung:>> Ich melde mich momentan von einem Ubuntu-Rechner an einem anderen Gerät> per Terminal / ssh an, gebe mein Kennwort ein, tippe dann ein paar> Befehle und bekomme Daten, die ich mir kopiere und auf meinem Rechner> weiterverwende.>> Nun würde ich das gerne automatisieren,
sshpass(1) wurde bereits erwähnt, ist aber aus Sicherheitssicht unschön
-- daß ssh(1) nur eine interaktive Paßworteingabe zuläßt, hat ja Gründe.
Aber wenn Du zudem auch noch Befehle auf der Gegenseite ausführen
willst, sind Python und dessen Modul "paramiko" vielleicht etwas für
Dich.
Sheeva P. schrieb:> Aber wenn Du zudem auch noch Befehle auf der Gegenseite ausführen> willst, sind Python und dessen Modul "paramiko" vielleicht etwas für> Dich.
Klingt mir ein bischen nach overkill .. aber wenn ich nichts anderes
finde, versuche ich das...
Julius J. schrieb:> Expect ist dafür erfunden worden.> https://debaan.blogspot.de/2007/09/simple-expect-ssh-example.html
Klingt interessant, mal sehen, ob ich das Script verstehe.
Ich hab mir mal das "Except" script angeschaut und es so verstanden wie
unten immer in der Zeile davor kommentiert (ist das richtig?)
#lies Kommandos aus dieser Datei
#!/usr/bin/expect
#keine Ahnung wofür
set timeout 1
#keine Ahnung wofür
set cmd {uname -a}
#neuen Prozess starten, ssh mit root auf die Maschine aus dem
Aufrufparameter
spawn ssh root@$argv
#wenn eof (welcher Datei?) steig aus ohne Fehler
expect_after eof { exit 0 }
## interact with SSH
#wenn die ssh-session yes/no fragt, sende yes und RETURN
expect "yes/no" { send "yes\r" }
#dto
expect "password:" { send "rootpasswd\r" }
#keine Ahnung wozu
expect "# "
send "$cmd\r"
expect "$cmd\r"
expect "(.*)\r"
send "exit\r
# Zeit in Sekunden, die expect auf einen Match wartet, bis es beendet.
4
set timeout 1
5
6
# Kommando, welches remote ausgeführt werden soll, hier "uname -a". Hier wird eine Variable "cmd" definiert.
7
set cmd {uname -a}
8
9
#neuen Prozess starten, ssh mit root auf die Maschine aus dem
10
Aufrufparameter
11
spawn ssh root@$argv
12
13
# wenn ssh beendet wird, wird exit 0 ausgeführt. Expect bezieht sich auf das Programm, was mit "spawn" gestartet wurde.
14
expect_after eof { exit 0 }
15
16
17
## interact with SSH
18
#wenn die ssh-session yes/no fragt, sende yes und RETURN
19
expect "yes/no" { send "yes\r" }
20
#dto
21
expect "password:" { send "rootpasswd\r" }
22
23
# Die Raute zeigt, dass hier ein rootprompt vorliegt. ("root@xyz:/#")
24
# Als normaler user wäre hier expect {$ } eventuell ausreichend.
25
expect "# "
26
# sendet das in "set cmd .." festgelegte Kommando
27
send "$cmd\r"
28
# erwartet das Echo des Kommandos
29
expect "$cmd\r"
30
# erwartet einen beliebigen String, der mit \r endet. Naja. Besser ist es an dieser Stelle erneut auf den Prompt zu matchen, da dieser erscheint sobald das Kommando vorbei ist. Außer man erwartet genau eine Zeile.
31
expect "(.*)\r"
32
# Beendet ssh
33
send "exit\r
So würde ich das machen (ohne Gewähr):
1
#!/usr/bin/expect
2
3
set prompt {user@host:~$}
4
set cmd "ps aux"
5
6
spawn "ssh user@host"
7
8
expect {
9
-nocase "login:" {
10
exp_send "username\n"
11
exp_continue
12
}
13
-nocase "password:" {
14
exp_send "password\n"
15
exp_continue
16
}
17
$prompt {
18
# Prompt, d.h. Kommando kann gesendet werden
19
}
20
timeout {
21
# Hier beliebige Fehlerbehandlung einfuegen, falls von Interesse
22
}
23
}
24
exp_send "$cmd\n"
25
expect {
26
$prompt {
27
# Prompt, d.h. das Kommando ist durchgelaufen
28
}
29
timeout {
30
# Hier beliebige Fehlerbehandlung einfuegen, falls von Interesse
Also diese expect-Scripte sind recht nützlich. Jetzt habe ich noch eine
Frage zu "interact": Mal angenommen, ich mache eine shell per ssh so
auf:
spawn /usr/bin/ssh user@host
expect -nocase "password:" { interact }
Dann kann ich an dieser Stelle das Passwort eingeben und bin dann im
"interaktiven" Modus. Aber was muss ich tun, um diesen Modus wieder zu
verlassen, wenn ich danach mit send / expect weiter Kommandos senden
will, also als nächste Zeile
expect -nocase "/home/user$" { exp_send "help\n" }
?
Momentan bekomme ich dann den Fehler "expect: spawn id exp5 not open"
Entweder du machst dir einen eigenen Passwortdialog in deinem Tcl/Expect
script, welches dich vor dem ssh-Kommando nach einem Passwort fragt und
in einer Variable speichert.
Oder: was funktionieren könnte:
1
...
2
expect {
3
password: {
4
interact \r inter_return
5
}
6
....
interact wird, sobald ein "\r" eingegeben wird, beendet.
Problem ist jetzt aber, dass das \r (habs gerade kurz ausprobiert) nicht
gesendet wird. Lösung:
1
...
2
expect {
3
password: {
4
interact \r inter_return
5
exp_send \r
6
}
7
....
Das vom user eingegebene \r (also "Enter") wird von interact abgefangen.
Damit wird die Passwordeingabe beendet. Jetzt fehlt dem Remotelogin aber
noch ein \r, welche durch exp_send hinterhergeschickt wird.
edit: Statt "return" kann "inter_return" benutzt werden, dann bleibt die
spawn_id erhalten.