Automatisieren der Telnet-Sitzung mithilfe von Bash-Skripten


80

Ich arbeite daran, einige Telnet-bezogene Aufgaben mithilfe von Bash-Skripten zu automatisieren. Nach der Automatisierung erfolgt keine Interaktion des Benutzers mit Telnet. (das heißt, es wird vollständig automatisiert)

Das Skript sieht ungefähr so ​​aus:

# execute some commands on the local system
# access a remote system with an IP address: 10.1.1.1 (for example)

telnet 10.1.1.1

# execute some commands on the remote system
# log all the activity (in a file) on the Local system
# exit telnet
# continue on with executing the rest of the script.

Ich habe hier zwei Probleme:

  1. Wie führe ich die Befehle auf dem Remote-System aus dem Skript aus (ohne menschliche Interaktion)?

    Aus meiner Erfahrung mit einigen Testcodes konnte ich schließen, dass Telnet bei der Ausführung von Telnet 10.1.1.1 in eine interaktive Sitzung geht und die nachfolgenden Codezeilen im Skript auf dem lokalen System ausgeführt werden. Wie kann ich die Codezeilen auf dem Remote-System und nicht auf dem lokalen System ausführen?

  2. Ich kann keine Protokolldatei für die Aktivität in der Telnet-Sitzung auf dem lokalen System abrufen. Die von mir verwendete Standardumleitung erstellt eine Kopie auf dem Remote-System (ich möchte keinen Kopiervorgang ausführen, um das Protokoll auf das lokale System zu kopieren). Wie kann ich diese Funktionalität erreichen?

Antworten:


77

Schreiben Sie ein expectSkript.

Hier ist ein Beispiel:

#!/usr/bin/expect

#If it all goes pear shaped the script will timeout after 20 seconds.
set timeout 20
#First argument is assigned to the variable name
set name [lindex $argv 0]
#Second argument is assigned to the variable user
set user [lindex $argv 1]
#Third argument is assigned to the variable password
set password [lindex $argv 2]
#This spawns the telnet program and connects it to the variable name
spawn telnet $name 
#The script expects login
expect "login:" 
#The script sends the user variable
send "$user "
#The script expects Password
expect "Password:"
#The script sends the password variable
send "$password "
#This hands control of the keyboard over to you (Nice expect feature!)
interact

Laufen:

./myscript.expect name user password

2
Das "Erwarten" gilt hauptsächlich für interaktive Sitzungen. Was ich möchte, ist eine automatisierte nicht interaktive Sitzung. Das Problem besteht darin, dass ich die Skripte auf dem Remote-System (über Telnet) nicht ausführen kann, da alle Zeilen nach Telnet 10.1.1.1 auf dem lokalen Computer und nicht auf dem Computer ausgeführt werden, auf den ich zugreife.
Khan

3
Wie Thomas Telensky betonte, ist ssh je nach Ihren Bedürfnissen letztendlich einfacher. Aber erwarten kann völlig nicht interaktiv sein. Ich gehe davon aus, dass Sie meinen, dass alle Zeilen nach dem Telnet so sind, wie Sie es auf dem Remotecomputer ausführen möchten. Fügen Sie sie in diesem Fall einfach als Sendebefehle zum Expect-Skript hinzu und löschen Sie den Interaktionsbefehl. Aber ssh ist einfacher und sicherer.
Joemooney

2
Meinetwegen. Ich werde Expect für diese Aufgabe verwenden.
Khan

1
Eine weitere gute Ergänzung ist, dies zu lesen - elenako.com/2013/04/04/… , vorausgesetzt, das Skript hatte \ram Ende des Befehls keine Sequenz, und als ich auf Enter selbst klickte, funktionierte es aus irgendeinem Grund nicht
llamerr

87

Während ich vorschlagen würde, "Expect" auch für nicht interaktive Zwecke zu verwenden, könnten die normalen Shell-Befehle ausreichen. Telnet akzeptiert seinen Befehl auf stdin, sodass Sie nur die Befehle weiterleiten oder schreiben müssen:

telnet 10.1.1.1 <<EOF
remotecommand 1
remotecommand 2
EOF

(Bearbeiten: Den Kommentaren nach zu urteilen, benötigt der Remote-Befehl einige Zeit, um die Eingaben zu verarbeiten, oder das frühe SIGHUP wird vom Telnet nicht ordnungsgemäß ausgeführt. In diesen Fällen können Sie versuchen, die Eingabe kurz zu schlafen :)

{ echo "remotecommand 1"; echo "remotecommand 2"; sleep 1; } | telnet 10.1.1.1

In jedem Fall, wenn es interaktiv wird oder irgendetwas, verwenden Sie expect.


2
+1 sleepfunktioniert wie ein Traum ;-) Ich habe auch | tee /dev/tty |dazwischen hinzugefügt, um die volle Sitzung auf dem Bildschirm zu haben
;-)

1
in meinem Fall die hilfreichste Antwort, aber ich musste hinzufügenecho -e "command\r";
mf_

1
Wie gebe ich Telnet nicht interaktiv ein Passwort?
Geremia

{ echo "remotecommand 1"; echo "remotecommand 2"; sleep 1; } | telnet 10.1.1.1 : Dieses Beispiel entspricht meinen Anforderungen. Ich möchte nur wissen, wie wir eine Fehlerprüfung hinzufügen, wenn Telnet fehlschlägt und das Shell-Skript dies tun sollte exit 1.
Yash

44

Telnet wird häufig verwendet, wenn Sie das HTTP-Protokoll lernen. Ich habe dieses Skript als Teil meines Web-Scraper verwendet:

echo "open www.example.com 80" 
sleep 2 
echo "GET /index.html HTTP/1.1" 
echo "Host: www.example.com" 
echo 
echo 
sleep 2

Nehmen wir an, der Name des Skripts lautet dann get-page.sh:

get-page.sh | telnet

erhalten Sie ein HTML-Dokument.

Hoffe es wird jemandem helfen;)


1
Sehr hilfreicher Kommentar! Auf diese Weise können Sie das Senden von Befehlen automatisieren, indem Sie sie in eine Schleife
einfügen


Einzeileräquivalent : { echo "GET / HTTP/1.1"; echo "Host: www.example.com"; echo; sleep 1; } | telnet www.example.com 80. Beachten Sie, dass der Schlaf am Anfang nicht benötigt wird (es sei denn, Sie verwenden den Befehl open) und dass am Ende nur ein leeres Echo und Schlaf 1 anstelle von 2 benötigt wird.
Taufe

Wenn Sie jedoch HTTPS-Anforderungen ausführen müssen, sollten Sie netcat verwenden, auch bekannt als ncat oder nc:{ echo "GET / HTTP/1.1"; echo "Host: example.com"; echo; sleep 1; } | ncat --ssl example.com 443
Taufe

12

Das hat bei mir funktioniert ..

Ich habe versucht, mehrere Telnet-Anmeldungen zu automatisieren, für die ein Benutzername und ein Kennwort erforderlich sind. Die Telnet-Sitzung muss unbegrenzt im Hintergrund ausgeführt werden, da ich Protokolle von verschiedenen Servern auf meinem Computer speichere.

telnet.sh automatisiert die Telnet-Anmeldung mit dem Befehl 'expected'. Weitere Informationen finden Sie hier: http://osix.net/modules/article/?id=30

telnet.sh

#!/usr/bin/expect
set timeout 20
set hostName [lindex $argv 0]
set userName [lindex $argv 1]
set password [lindex $argv 2]

spawn telnet $hostName

expect "User Access Verification"
expect "Username:"
send "$userName\r"
expect "Password:"
send "$password\r";
interact

sample_script.sh wird verwendet, um einen Hintergrundprozess für jede der Telnet-Sitzungen zu erstellen, indem telnet.sh ausgeführt wird. Weitere Informationen finden Sie im Kommentarbereich des Codes.

sample_script.sh

#!/bin/bash
#start screen in detached mode with session-name 'default_session' 
screen -dmS default_session -t screen_name 
#save the generated logs in a log file 'abc.log' 
screen -S default_session -p screen_name -X stuff "script -f /tmp/abc.log $(printf \\r)"
#start the telnet session and generate logs
screen -S default_session -p screen_name -X stuff "expect telnet.sh hostname username password $(printf \\r)"
  1. Stellen Sie mit dem Befehl 'screen -ls' sicher, dass im Hintergrund kein Bildschirm ausgeführt wird.
  2. Lesen Sie http://www.gnu.org/software/screen/manual/screen.html#Stuff , um mehr über den Bildschirm und seine Optionen zu erfahren.
  3. Die Option '-p' in sample_script.sh wählt ein bestimmtes Fenster vor und fügt es erneut hinzu, um einen Befehl über die Option '-X' zu senden. Andernfalls wird der Fehler 'Keine Bildschirmsitzung gefunden' angezeigt.

2

Sie können Expect-Skripte verwenden, die von Bash installiert wurden. Das folgende Beispiel zeigt, wie eine Verbindung zu einer eingebetteten Karte ohne Kennwort hergestellt wird

#!/usr/bin/expect

set ip "<ip>"

spawn "/bin/bash"
send "telnet $ip\r"
expect "'^]'."
send "\r"
expect "#"
sleep 2

send "ls\r"
expect "#"

sleep 2
send -- "^]\r"
expect "telnet>"
send  "quit\r"
expect eof

2

Das Folgende funktioniert für mich ... Geben Sie alle Ihre IP-Adressen, die Sie telneten möchten, in IP_sheet.txt ein

while true
read a
do
{
    sleep 3
    echo df -kh
    sleep 3
    echo exit
} | telnet $a
done<IP_sheet.txt

1
#!/bin/bash
ping_count="4"
avg_max_limit="1500"
router="sagemcom-fast-2804-v2"
adress="192.168.1.1"
user="admin"
pass="admin"

VAR=$(
expect -c " 
        set timeout 3
        spawn telnet "$adress"
        expect \"Login:\" 
        send \"$user\n\"
        expect \"Password:\"
        send \"$pass\n\"
        expect \"commands.\"
        send \"ping ya.ru -c $ping_count\n\"
        set timeout 9
        expect \"transmitted\"
        send \"exit\"
        ")

count_ping=$(echo "$VAR" | grep packets | cut -c 1)
avg_ms=$(echo "$VAR" | grep round-trip | cut -d '/' -f 4 | cut -d '.' -f 1)

echo "1_____ping___$count_ping|||____$avg_ms"
echo "$VAR"

0

Verwenden Sie dazu ssh. Generieren Sie Schlüssel ohne Verwendung eines Kennworts und platzieren Sie es in .authorized_keys auf dem Remotecomputer. Erstellen Sie das Skript, das remote ausgeführt werden soll, kopieren Sie es auf den anderen Computer und führen Sie es dann einfach mit ssh remote aus.

Ich habe diesen Ansatz viele Male mit großem Erfolg angewendet. Beachten Sie auch, dass es viel sicherer als Telnet ist.


1
sshist sicherlich sicherer als telnet, aber einige IP-Geräte bieten einfach keinen sshDienst und verlassen sich auf ein telnetProtokoll für die Verwendung des Geräts.
fduff

2
Telnet (das Programm) kann als Client für JEDE (oder praktisch die meisten) textbasierten Client / Server-Verbindungen verwendet werden. Es kann zum einfachen Testen verwendet werden, z. B. HTTP und IMAP. @Tomas 'Vorschlag ist, die Verwendung von Telnet (dem Remote-Anmeldedienst) durch SSH zu ersetzen. Obwohl sein Kommentar wahr ist, ist es wahrscheinlich nicht das, was das OP verlangte.
Rob Shepherd

Rob, Telnet kann zwar verwendet werden, um eine Verbindung zu einem beliebigen Port herzustellen, aber siehe die Frage der OPs - in seinem Kontext möchte er Telnet nur für die Anmeldung verwenden (unter Berufung auf "Einige Befehle auf dem Remote-System ausführen" ). Die Verwendung von Telnet für diesen Zweck ist sehr riskant.
TMS

Dies ist keine Antwort auf die Frage, die speziell besagt, dass einige Telnet-bezogene Aufgaben mithilfe seiner vorhandenen Skripte automatisiert werden sollen.
FractalSpace

0

Hier erfahren Sie, wie Sie Telnet in Bash Shell / Expect verwenden

#!/usr/bin/expect
# just do a chmod 755 one the script
# ./YOUR_SCRIPT_NAME.sh $YOUHOST $PORT
# if you get "Escape character is '^]'" as the output it means got connected otherwise it has failed

set ip [lindex $argv 0]
set port [lindex $argv 1]

set timeout 5
spawn telnet $ip $port
expect "'^]'."

0

Skript zum Abrufen der Version von CISCO-Servern:

#!/bin/sh

servers='
192.168.34.1
192.168.34.3
192.168.34.2
192.168.34.3
'
user='cisco_login'
pass='cisco_password'

show_version() {
host=$1
expect << EOF
set timeout 20
set host $host
set user $user
set pass $pass
spawn telnet $host
expect "Username:"
send "$user\r"
expect "Password:"
send "$pass\r"
expect -re ".*#"
send "show version\r"
expect -re ".*-More-.*"
send " "
expect -re ".*#"
send "exit\r"
EOF
}

for ip in $servers; do
  echo '---------------------------------------------'
  echo "$ip"
  show_version $ip | grep -A3 'SW Version'
done

-4

Spielen Sie mit tcpdumpoder wiresharkund sehen Sie, welche Befehle an den Server selbst gesendet werden

Versuche dies

printf (printf "$username\r\n$password\r\nwhoami\r\nexit\r\n") | ncat $target 23

Einige Server erfordern eine Verzögerung mit dem Kennwort, da es keine Zeilen auf dem Stapel enthält

printf (printf "$username\r\n";sleep 1;printf "$password\r\nwhoami\r\nexit\r\n") | ncat $target 23**

9
Neuheit ist keine Entschuldigung für Unhöflichkeit. Bitte lesen Sie die FAQ stackoverflow.com/faq .
Verbeia

1
sollte nicht beleidigend sein, eher wie ... ich weiß nicht, Entschuldigung. Ich sehe immer wieder Leute, die den Befehl "Erwarten" als Lösung verwenden. Ich möchte nur, dass die Leute erkennen, dass es eine bessere Lösung gibt, um zu verstehen, was Sie erreichen wollen. Der Befehl "accept" zeigt Ihnen nicht, wie er funktioniert, sondern ist nur eine Problemumgehung, wenn Sie ihn nicht kennen. Es ist verwirrender als nicht. Im Zweifelsfall zur Quelle gehen. Wenn die Quelle nicht verfügbar ist und es sich um ein Netzwerkprotokoll handelt, tcpdump, wireshark, schnüffeln Sie die Pakete und folgen Sie dem Befehlsablauf, und Sie sollten in der Lage sein, etwas mit funktionierenden Kenntnissen zusammenzustellen.
Str8

7
Wenn Sie das sagen - ich bin ein Mathematica-Programmierer, daher ist mir die Substanz Ihrer Antwort und Ihres Kommentars ein Rätsel. Aber ich bin nicht der Einzige, der das Wort "Idioten" als absichtlich beleidigend interpretiert. Ich denke, Sie müssen ein bisschen mehr Zeit auf der Website verbringen und sehen, wie sich die Leute hier verhalten.
Verbeia
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.