Solved

Using Telnet from a Shell script (no, really)

Posted on 2008-10-27
28
1,996 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
ID: 22814953
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
ID: 22814991
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
ID: 22815041
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
ID: 22817787
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
ID: 22820490
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
ID: 22824565
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
ID: 22824651
0
 

Author Comment

by:ktwdallas
ID: 22824711
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
ID: 22824725
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
ID: 22824743
(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
ID: 22824758
you can get autoexpect from:

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

Author Comment

by:ktwdallas
ID: 22827076
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
ID: 22827264
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
ID: 22827472
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
Efficient way to get backups off site to Azure

This user guide provides instructions on how to deploy and configure both a StoneFly Scale Out NAS Enterprise Cloud Drive virtual machine and Veeam Cloud Connect in the Microsoft Azure Cloud.

 

Author Comment

by:ktwdallas
ID: 22827475
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
ID: 22827503
stupid question : do you have telnet installed and in $PATH ? :)

(which telnet)
0
 

Author Comment

by:ktwdallas
ID: 22827514
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
ID: 22827543
[rec@rec bin]$ rpm -qa | grep telnet
telnet-0.17-38.fc7
0
 
LVL 5

Expert Comment

by:zmo
ID: 22827579
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
ID: 22829527
so still at the same state ?
0
 
LVL 40

Expert Comment

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

Author Comment

by:ktwdallas
ID: 22833105
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
ID: 22833130
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
ID: 22833224
from the error message it is complaining about " somewhere in your copied file

0
 

Author Comment

by:ktwdallas
ID: 22833310
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
ID: 22833396
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
ID: 22833427
-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
ID: 22833640
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

Enterprise Mobility and BYOD For Dummies

Like “For Dummies” books, you can read this in whatever order you choose and learn about mobility and BYOD; and how to put a competitive mobile infrastructure in place. Developed for SMBs and large enterprises alike, you will find helpful use cases, planning, and implementation.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

How to remove superseded packages in windows w60 or w61 installation media (.wim) or online system to prevent unnecessary space. w60 means Windows Vista or Windows Server 2008. w61 means Windows 7 or Windows Server 2008 R2. There are various …
This article will show, step by step, how to integrate R code into a R Sweave document
Learn how to match and substitute tagged data using PHP regular expressions. Demonstrated on Windows 7, but also applies to other operating systems. Demonstrated technique applies to PHP (all versions) and Firefox, but very similar techniques will w…
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 …

920 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

17 Experts available now in Live!

Get 1:1 Help Now