Linux cron job ssh und Daten abholen

Gast #5065985
Lesenswert?

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..
#5066086
Lesenswert?

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.
Gast #5066125
Lesenswert?

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.
Gast #5066151
Lesenswert?

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
#5066199
Lesenswert?

So, ich antworte mal in den Kommentarzeilen:
1
#!/usr/bin/expect
2

3
# 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
31
    }
32
}
33
exit 0

edit: Formatierung
Gast #5067213
Lesenswert?

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"
#5067358
Lesenswert?

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.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren