Solved

Using Telnet from a Shell script (no, really)

Posted on 2008-10-27
28
1,992 Views
Last Modified: 2012-05-05
First off, I've searched for examples of telnet through a shell script and every response always starts back "use SSH, here's an example"... but I can't use SSH in this scenario. I'm using telnet to connect to a video playback box (Adtec) and it's the controller program that actually responds on port 23 to control what the box is playing. (SSH is hooked up, but it's standard SSH to get to the file system and that's not what I'm interested in.)

So ... what I'm trying to accomplish is to use a shell script (which will be a cron job) that telnet's to the box, logs in, and then stays in a loop and every 10 seconds issues a "status" command. The status command is just a single line (05 "30min.mpg" 3315907 01 00 00 010 0007726 10 25 2008 108 25 00 32 04 148 53 44) and I have take that string and submit it as part of a URL.

I have the second part from an earlier script, mostly I just need an example of logging in through telnet and issuing the command.
0
Comment
Question by:ktwdallas
  • 12
  • 9
  • 6
  • +1
28 Comments
 
LVL 6

Assisted Solution

by:dathho
dathho earned 100 total points
Comment Utility
A start...
take a look at man expect also.
------------------------------

#!/bin/sh

host=10.0.0.1

port=23

login=username

passwd=password

cmd="/var/script/mycommands.sh"
 

echo open $host $port

sleep 1

echo $login

sleep 1

echo $passwd

sleep 1

echo $cmd

sleep 1

echo exit

Open in new window

0
 
LVL 40

Expert Comment

by:omarfarid
Comment Utility
use expect. Please see the link below:

http://www.experts-exchange.com/Programming/Languages/Scripting/Shell/Q_23682114.html

see the first link for telnet example
0
 
LVL 5

Expert Comment

by:zmo
Comment Utility
I'd advice you using netcat instead of telnet, which is more handy.

the following solution may not be exactly what you expected, but you'll have all the basic things you need to do it how you want. All it does, is send status every 10 seconds in script2, and script1 will log the results in the results file.
script 1 :

mknod backpipe p

nc host port 0 < backpipe >> results
 

script 2 :

while true; do

    sleep 10;

    echo "status" > backpipe

Open in new window

0
 

Author Comment

by:ktwdallas
Comment Utility
So I basically have it working now where it's connecting, logging and issuing the command (which is just "status" .. the long string above is the result string, not the command.. that was a typo).

So what I need to do is get the result string that I get back and put it in a variable.. I can't seem to figure out the way to do that. Waiting for specific strings and issuing commands, no problem, but how do I get the result back.. This is current where I'm at:
#!/usr/bin/expect -f
 

spawn telnet "machine.domain.org"

expect "UserName:"

send "myuser\r"

expect "PassWord:"

send "mypass\r"

expect "connected"

send "*.* TR\r"

$result (should be result of TR command??)

firsturl="http://www.mydomain.com/setstatus.php?theresult="$result

curl $completeurl

Open in new window

0
 
LVL 5

Expert Comment

by:zmo
Comment Utility
on wikipedia's expect page there's a telnet example with something that can interest you :
<http://en.wikipedia.org/wiki/Expect>
...

# Send the prebuilt command, and then wait for another shell prompt.

send "$my_command\r"

expect "%"

# Capture the results of the command into a variable. This can be displayed, or written to disk.

set results $expect_out(buffer)

...

Open in new window

0
 

Author Comment

by:ktwdallas
Comment Utility
I'm close but getting an error message.

For comparison purposes, this is the transcript for MANUALLY telneting into the box and typing the commands:


telnet xxxxxx.dyndns.org
Trying 640.1.1.1...
Connected to xxxxxx.dyndns.org.
Escape character is '^]'.

Adtec Resident Telnet Server...
UserName:
adtec
PassWord:
[passwordentered]
User adtec connected
*.* TRANSPORT
?

OK
PLAYING  "/media/hd0/media/TuTh/Winnipeg.mpg" 3315.865 Mbytes 00:59:59.940 7.72 Mbps 10/28/2008 2:14 00:05:19.378  8.87%

So the items I enter are the userID, the password, and the command *.* TRANSPORT -- everything else, starting with the question mark is the returned results. What I need is the line that starts PLAYING .. so I put in an expect with a % which is the last character on that result string (normally % is a prompt, I don't have a prompt here, so the % is just pure coincidence because it's a percentage measurement)



The result from running the script is as follows. (The Code Snippet is the actual script .sh file).

./checkwin.sh
spawn telnet xxxxxx.dyndns.org
Trying 640.1.1.1...
Connected to xxxxxx.dyndns.org.
Escape character is '^]'.

Adtec Resident Telnet Server...
UserName:
adtec
PassWord:
User adtec connected
*.* TRANSPORT
?

OK
PLAYING  "/media/hd0/media/TuTh/Winnipeg.mpg" 3315.865 Mbytes 00:59:59.940 7.72 Mbps 10/28/2008 2:14 00:09:50.085 16.39%

invalid command name "completeurl="http://www.mydomain.com/ctrl/statuswin.php?theresult="
*.* TRANSPORT
?

OK
PLAYING  "/media/hd0/media/TuTh/Winnipeg.mpg" 3315.865 Mbytes 00:59:59.940 7.72 Mbps 10/28/2008 2:14 00:09:50.085 16.39%"
    while executing
"completeurl="http://www.mydomain.com/ctrl/statuswin.php?theresult="$expect_out(buffer)"
    (file "./checkwin.sh" line 12)
Kwhite:~ kwhite$

#!/usr/bin/expect -f
 

spawn telnet "xxxxxx.dyndns.org"

expect "UserName:"

send "adtec\r"

expect "PassWord:"

send "mypass\r"

expect "connected"

send "*.* TRANSPORT\r"

expect "%"
 

completeurl="http://www.mydomain.com/ctrl/statuswin.php?theresult="$expect_out(buffer)

curl $completeurl

Open in new window

0
 
LVL 40

Expert Comment

by:omarfarid
Comment Utility
0
 

Author Comment

by:ktwdallas
Comment Utility
hmm. that doesn't seem to be available either on Terminal in the Mac or on by Fedora 7 box...
0
 
LVL 5

Assisted Solution

by:zmo
zmo earned 300 total points
Comment Utility
well, you're not getting it.
by using

"#!/usr/bin/expect -f"

you're not writing a shell script, but you're actually writing a TCL script.

so the syntax VAR=VALUE is not valid as with /bin/sh
you have to use 'set VAR VALUE'

so I should have corrected your error.

I also expect an error with curl

you can execute
    package require TclCurl
    curl::transfer -url $completeurl

or

    exec curl $completeurl

I'm not a TCL expert at all, so you may refer to :

http://www.tcl.tk/man/tcl8.5/tutorial/tcltutorial.html (TCL tutorial)
http://personal1.iddeo.es/andresgarci/tclcurl/english/examples.html (TCL libcurl)
#!/usr/bin/expect -f

 

spawn telnet "xxxxxx.dyndns.org"

expect "UserName:"

send "adtec\r"

expect "PassWord:"

send "mypass\r"

expect "connected"

send "*.* TRANSPORT\r"

expect "%"
 

set completeurl "http://www.mydomain.com/ctrl/statuswin.php?theresult="$expect_out(buffer)

curl $completeurl

Open in new window

0
 
LVL 5

Expert Comment

by:zmo
Comment Utility
(or maybe this one is better... you have to try out)

set completeurl "http://www.mydomain.com/ctrl/statuswin.php?theresult=$expect_out(buffer)"
0
 
LVL 40

Expert Comment

by:omarfarid
Comment Utility
you can get autoexpect from:

http://expect.nist.gov/example/autoexpect
0
 

Author Comment

by:ktwdallas
Comment Utility
I'm SOOO close on this. I have the script working perfectly inside Terminal on my Mac Pro. Works great. Then I copied it to our webserver running Fedora 7, chmod 755, and now I'm getting a cryptic error message

": no such file or directory

when attempting to run it.

I had to install expect, which I did via yum, and that's now working and verified. (I get an "expect1.1>" prompt when running it manually on the Fedora box, same as on the Mac.)
#!/usr/bin/expect -f
 

spawn telnet "xxxxxxx.dyndns.org"

expect "UserName:"

send "adtec\r"

expect "PassWord:"

send "mypass\r"

expect "connected"

send "*.* TRANSPORT\r"

expect "%"

set old_line $expect_out(buffer)

regsub -all {[^a-z ]} $old_line "" words
 

set clean_line [string map {" " | "\r" "" "\n" ""} $old_line]
 

set completeurl "http://www.realestatechannel.ca/ctrl/statuswin.php?theresult=$clean_line"

exec curl --silent $completeurl
 

send "quit\r"

Open in new window

0
 
LVL 5

Expert Comment

by:zmo
Comment Utility
well, it's hard to tell you what could be the origin of the error... maybe it's curl not working (or not installed) or \r misinterpreted or I don't really see what other error it could be.

the only advice I could give you to track it down is to comment the code logical block by logical block and fine search it until you get what's wrong...

(ie comment everything after the send/expect part and uncomment everything line by line)
0
 

Author Comment

by:ktwdallas
Comment Utility
I'm not even getting past the first command after removing everything else:


[rec@rec bin]$ /home/rec/checkwin.sh
": no such file or directory


#!/usr/bin/expect -f
 

spawn telnet xxxxxx.dyndns.org

Open in new window

0
How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

 

Author Comment

by:ktwdallas
Comment Utility
verifying expect is there


[rec@rec bin]$ cd /usr/bin
[rec@rec bin]$ ls -ld expect
-rwxr-xr-x 1 root root 4872 2007-02-10 13:41 expect
0
 
LVL 5

Expert Comment

by:zmo
Comment Utility
stupid question : do you have telnet installed and in $PATH ? :)

(which telnet)
0
 

Author Comment

by:ktwdallas
Comment Utility
Telnet is installed and I can manually telnet from the Fedora machine to the machine I'm connecting to. It's whatever was installed as part of Core 7 (Godaddy server).
0
 

Author Comment

by:ktwdallas
Comment Utility
[rec@rec bin]$ rpm -qa | grep telnet
telnet-0.17-38.fc7
0
 
LVL 5

Expert Comment

by:zmo
Comment Utility
hm... do you have the same version of expect on both computers ?
do you also have the same version of tcl on both computers ? (tcl tends to break backward compatibility)
does your expect really accept '-f' option ?
is expect really in /usr/bin/expect ?
can you try to change telnet to the full path to telnet and see if anything changes ?
can you try adding quotes around your xxx.dyndns.org ?

I'm also running out of ideas... but for sure it's really something stupid

I'm getting to bed now, so hope you'll find a solution till tomorrow ;)
0
 
LVL 5

Expert Comment

by:zmo
Comment Utility
so still at the same state ?
0
 
LVL 40

Expert Comment

by:omarfarid
Comment Utility
put the full path to telnet in the script (which telnet will give the path)
0
 

Author Comment

by:ktwdallas
Comment Utility
Sorry, just back into work this morning (west coast). The quotes were actually on there, just didn't have them on the sample but it makes no difference. Removing the -f option actually causes an error:

-bash: ./checkwin.sh: /usr/bin/expect^M: bad interpreter: No such file or directory

expect really is in /usr/bin, not a symbolic link.

changing to spawn /usr/bin/telnet makes no difference

As far as versions, the rpm doesn't exist on the Mac.. I'm honestly not sure how to check version numbers there. (It's Leopard with all the latest updates).

On the Fedora box, the results are:

[rec@rec ~]$ rpm -qa | grep telnet
telnet-0.17-38.fc7
[rec@rec ~]$ rpm -qa | grep expect
expect-5.43.0-8
[rec@rec ~]$ rpm -qa | grep tcl
tcl-8.4.13-19.fc7
tclx-8.4.0-7.fc7
0
 

Author Comment

by:ktwdallas
Comment Utility
so why would the lack of -f give a "bad interpreter" if the file really is there?

[rec@rec bin]$ pwd
/usr/bin
[rec@rec bin]$ ls -la expect
-rwxr-xr-x 1 root root 7984 2007-02-10 13:41 expect
[rec@rec bin]$


0
 
LVL 40

Expert Comment

by:omarfarid
Comment Utility
from the error message it is complaining about " somewhere in your copied file

0
 

Author Comment

by:ktwdallas
Comment Utility
That's why I tested without the quotes...  I'm getting this error even on just a two-line script, the only quotes surround the url.
#!/usr/bin/expect -f
 

spawn /usr/bin/telnet "xxxxxx.dyndns.org"

Open in new window

0
 
LVL 40

Assisted Solution

by:omarfarid
omarfarid earned 100 total points
Comment Utility
you say that it isworking from the command line or terminal while it fails when you copied it to web server.

what is the difference between the two?

0
 
LVL 5

Accepted Solution

by:
zmo earned 300 total points
Comment Utility
-bash: ./checkwin.sh: /usr/bin/expect^M: bad interpreter: No such file or directory

means it did not take the "^M" as a carriage return. it may be because of a wrong file encoding.

that may be the reason spawn is not working correctly.
What editor do you use to edit the file ?

MacOS historically uses '\r' as carriage return, where unix uses '\n'.
So if your file was created using a traditional MacOS editor, it may have been encoded in MacOS format.
Though when editing your file under unix you used '\n' when inserting a carriage return...

it is worth investigating this way, though there's no evidence this is the reason.

to check this out, edit your file using vim, and type
:set fileencoding
:set encoding
(:q! to quit)

you should see "latin1" for both, or fileencoding being empty and encoding=latin1.
0
 

Author Comment

by:ktwdallas
Comment Utility
ok, finally got it to work. File extension was still .sh, changed to .tcl, don't know if Fedora or expect cares about that or not.

The file I copied was the file I made on the Mac and even though BBEdit said it was Unix (LF), I ended up just using vi to create a new file, pasted in the text through Terminal, saved, chmod +x and it runs. So that's it, we're running.

Thanks for everyone's help.

Kris
0

Featured Post

How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

Join & Write a Comment

Suggested Solutions

Title # Comments Views Activity
how to run my script during boot in rhel 7 14 78
Squid Authentication 7 31
Port ssh and port rsysc are different 2 58
Issue to mail 11 36
Linux users are sometimes dumbfounded by the severe lack of documentation on a topic. Sometimes, the documentation is copious, but other times, you end up with some obscure "it varies depending on your distribution" over and over when searching for …
The purpose of this article is to demonstrate how we can use conditional statements using Python.
The viewer will learn how to create a basic form using some HTML5 and PHP for later processing. Set up your basic HTML file. Open your form tag and set the method and action attributes.: (CODE) Set up your first few inputs one for the name and …
This demo shows you how to set up the containerized NetScaler CPX with NetScaler Management and Analytics System in a non-routable Mesos/Marathon environment for use with Micro-Services applications.

744 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

15 Experts available now in Live!

Get 1:1 Help Now