Automating telnet session using bash scripts

310,590

Solution 1

Write an expect script.

Here is an example:

#!/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

To run:

./myscript.expect name user password

Solution 2

While I'd suggest using expect, too, for non-interactive use the normal shell commands might suffice. telnet accepts its command on stdin, so you just need to pipe or write the commands into it through heredoc:

telnet 10.1.1.1 <<EOF
remotecommand 1
remotecommand 2
EOF

(Edit: Judging from the comments, the remote command needs some time to process the inputs or the early SIGHUP is not taken gracefully by telnet. In these cases, you might try a short sleep on the input:)

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

In any case, if it's getting interactive or anything, use expect.

Solution 3

Telnet is often used when you learn HTTP protocol. I used to use that script as a part of my web-scraper:

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

let's say the name of the script is get-page.sh then:

get-page.sh | telnet

will give you a html document.

Hope it will be helpful to someone ;)

Solution 4

This worked for me..

I was trying to automate multiple telnet logins which require a username and password. The telnet session needs to run in the background indefinitely since I am saving logs from different servers to my machine.

telnet.sh automates telnet login using the 'expect' command. More info can be found here: 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 is used to create a background process for each of the telnet sessions by running telnet.sh. More information can be found in the comments section of the code.

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. Make sure there is no screen running in the backgroud by using the command 'screen -ls'.
  2. Read http://www.gnu.org/software/screen/manual/screen.html#Stuff to read more about screen and its options.
  3. '-p' option in sample_script.sh preselects and reattaches to a specific window to send a command via the ‘-X’ option otherwise you get a 'No screen session found' error.

Solution 5

You can use expect scripts instaed of bash. Below example show how to telnex into an embedded board having no password

#!/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
Share:
310,590

Related videos on Youtube

khan
Author by

khan

Updated on June 03, 2021

Comments

  • khan
    khan about 3 years

    I am working on automating some telnet related tasks, using Bash scripts. Once automated there will be no interaction of the user with telnet (that is it will be totally automated)

    The scripts looks something like this:

    # 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.
    

    There are 2 problems I am facing here:

    1. How to execute the commands on the remote system from the script (without human interaction)?

      From my experience with some test codes, I was able to deduce that when the telnet 10.1.1.1 is executed, telnet goes into an interactive session and the subsequent lines of code in the script are executed on the local system. How can I run the lines of code on the remote system rather than the local one?

    2. I am unable to get a log file for the activity in the telnet session on the local system. The stdout redirect I used makes a copy on the remote system (I do not want to perform a copy operation to copy the log to the local system). How can I achieve this functionality?

  • khan
    khan almost 13 years
    the 'expect' is mostly for interactive sessions. What I want is an automated non-interactive session. the problem I am facing is that I am unable run the scripts on the remote system (via telnet) as all the lines following the telnet 10.1.1.1 are executed on the local machine rather than the machine I am accessing.
  • joemooney
    joemooney almost 13 years
    As Thomas Telensky pointed out depending on your needs ssh is ultimately easier. But expect can be completely non-interactive. I am assuming that you mean that all the lines following the telnet are what you want executed on the remote machine in that case just add them to the expect script as send commands and delete the interact command. But ssh is easier and more secure.
  • khan
    khan almost 13 years
    fair enough. I will be using expect for this task.
  • Verbeia
    Verbeia over 12 years
    Newness is no excuse for rudeness. Please see the FAQ stackoverflow.com/faq.
  • str8
    str8 over 12 years
    wasn't meant to be insulting, more like... i dont know, apologies. I just keep seeing people using expect command as a solution. I just want people to realize there is a better solution to understanding what you are trying to accomplish. The expect command doesn't show you how its working, its just a workaround for not knowing. It is more confusing then not. When in doubt go to the source. If the source is not available, and if its a network protocol, tcpdump,wireshark,snoop the packets and follow the command flow and you should be able to put something together with working knowledge.
  • Verbeia
    Verbeia over 12 years
    If you say so - I'm a Mathematica programmer so the substance of your answer and comment is a mystery to me. But I am not alone in interpreting the word "idiots" to be intentionally insulting. I think you need to spend a bit more time on the site and see how people behave here.
  • fduff
    fduff over 10 years
    ssh is surely more secure than telnet, but some IP devices just do not provide ssh service and rely on telnet protocol for using the device.
  • Rob Shepherd
    Rob Shepherd over 10 years
    telnet (the program) can be used as a client for ANY (or more practically MOST) text-based client/server connections. It can be used for easy testing, for example, HTTP and IMAP. @Tomas' suggestion is to replace the use of Telnet (the remote login service) with SSH. whilst his comment is true, it is probably not what the OP was requiring.
  • Tomas
    Tomas over 10 years
    Rob, telnet can be indeed used to connect to any port, but see the OPs question - in his context he wants to use telnet only for login (citing: "execute some commands on the remote system"). Using telnet for this purpose is very risky.
  • RomanM
    RomanM over 9 years
    Most helpful comment ! This actually lets you automate sending commands by putting them in a loop
  • leomeurer
    leomeurer over 9 years
  • paluh
    paluh over 7 years
    +1 sleep works like a dream ;-) I've also added | tee /dev/tty | in between to have full session on the screen ;-)
  • mf_
    mf_ almost 6 years
    in my case, the most helpfull answer, but i had to add echo -e "command\r";
  • FractalSpace
    FractalSpace over 5 years
    This is not an answer to the question which specifically says 'automating some telnet related tasks' using his existing scripts.
  • Geremia
    Geremia about 5 years
    How do I supply a password to telnet non-interactively?
  • baptx
    baptx about 5 years
    One-liner equivalent: { echo "GET / HTTP/1.1"; echo "Host: www.example.com"; echo; sleep 1; } | telnet www.example.com 80. Note that the sleep is not needed at the beginning (unless you use the open command) and that only one empty echo and sleep 1 instead of 2 is needed at the end.
  • baptx
    baptx about 5 years
    But if you need to do HTTPS requests, you should use netcat, also known as ncat or nc: { echo "GET / HTTP/1.1"; echo "Host: example.com"; echo; sleep 1; } | ncat --ssl example.com 443
  • Yash
    Yash over 3 years
    { echo "remotecommand 1"; echo "remotecommand 2"; sleep 1; } | telnet 10.1.1.1 : This example meets my requirements. Just want to know how do we add error check if telnet fails and the shell script should exit 1.
  • Mithun B
    Mithun B over 3 years
    Very helpful. This get the output on the screen. Is there anyway I can wait for a known string from telnet and then run my next command, instead of sleep?
  • Mithun B
    Mithun B over 3 years
    Another case is if I get an error like: telnet: Unable to connect to remote host: No route to host, I should exit. How can I handle that? So the sleep can't be a good option here.
  • tripleee
    tripleee about 3 years
    Whether the remote server requires quit or exit or something else depends entirely on what's at the other end. The command gets sent to the remote server, not to the telnet client as such (other than as input which it outputs to the other end). Perhaps you can edit to clarify that?
  • kapex
    kapex about 3 years
    @tripleee Thanks that's good to know. I was actually surprised that quit worked without using the ^] escape, when I tried it in the telnet client. I'll clarify that in the answer later. Do you know if it's possible to quit from the client side in a script, when using telnet (or curl), without relying on the server behaviour?
  • tripleee
    tripleee about 3 years
    Actually I would be very surprised if curl obeyed the same escape mechanism as traditional telnet, and based on brief experimentation, it seems it indeed doesn't. stackoverflow.com/questions/42347271/… suggests using a timeout; the manual does not mention anything for out-of-band commands.