LinuxQuestions.org
Share your knowledge at the LQ Wiki.
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 08-24-2012, 02:22 PM   #1
chimpsky
LQ Newbie
 
Registered: Aug 2012
Posts: 9

Rep: Reputation: Disabled
Directing File IO in Expect Script


Hello!

I have a simple Expect script (executed within a bash script) that spawns a SSH connection to a remote host and then begins to interact with a program on the remote host. I want to send the contents of a binary file to this program on the remote host, but I’m not exactly certain how to do this. For example:

Code:
spawn ssh user@remotehost interactiveProgram
expect ”password:” { send ”$user_ssh_password\r” }
expect ”ready for file” { send <FILE_CONTENTS> } #any ideas how this can be achieved???
Is there a way to simply direct the cat output of the binary file to the particular send section of the Expect script? The binary file in question is on the local host that is executing the bash/expect script. Any thoughts or suggestions would be appreciated. Please let me know if anything is unclear or if there are any questions.

Thanks!
 
Old 08-25-2012, 07:43 AM   #2
jschiwal
LQ Guru
 
Registered: Aug 2001
Location: Fargo, ND
Distribution: SuSE AMD64
Posts: 15,733

Rep: Reputation: 677Reputation: 677Reputation: 677Reputation: 677Reputation: 677Reputation: 677
Why use expect? Use public key authentication to login. Then use scp to send the file.

To transfer a file using cat, you can run ssh to the right of a pipe.
cat file | ssh user@server "cat >remotefile"

Sometimes tar is used this way to transfer files to a remote host.

Using a passphrase in a script can be a security risk.
 
Old 08-25-2012, 07:31 PM   #3
chimpsky
LQ Newbie
 
Registered: Aug 2012
Posts: 9

Original Poster
Rep: Reputation: Disabled
Thanks for the reply. My access to the remote host is extremely limited. The shell I'm provided can do pretty much nothing but execute the program.

BTW, the password is given as an argument when the bash script is executed on the local host so I don't have to store it in plain text.
 
Old 08-26-2012, 07:18 AM   #4
jschiwal
LQ Guru
 
Registered: Aug 2001
Location: Fargo, ND
Distribution: SuSE AMD64
Posts: 15,733

Rep: Reputation: 677Reputation: 677Reputation: 677Reputation: 677Reputation: 677Reputation: 677
Since the server has an ssh server, scp may work. It looks as if instead of a shell, a default script is run instead. How would you do it manually? If text after send is saved to a file, you could use $(cat filename). Even using expect, file transfer is normally done automating file transfer tools such as ftp, sftp or scp. How is the text supposed to be terminated? What kind of data is being sent? Simply cat'ing the bytes across, the server doesn't know a filename.
 
Old 08-27-2012, 02:33 PM   #5
chimpsky
LQ Newbie
 
Registered: Aug 2012
Posts: 9

Original Poster
Rep: Reputation: Disabled
I tried SCP, but it didn't work (the remote host returns "Command not recognized"). As you say, it appears I'm interacting with a script rather than a shell.

The program is used to manage some datacenter hardware. The file I'm trying to send the program is a firmware file to update the hardware. The remote host is really just a proxy to allow me access to the hardware, which is on a separate network. The program has the capability to upload the firmware file to the hardware but, given the limited environment of the remote host / proxy, I'm not certain of the best way to get the contents of the file to the program running on the remote host. BTW, to answer your question about the transfer, no filename is needed. The contents are written directly to a network socket with some specific ASCII characters to initiate and terminate the transfer. Through Expect, I can setup and ready the hardware for the transfer. For termination, My plan was to append the termination sequence directly to the file so it would get passed along with the contents.

If I had full access to the remote host, I would copy the file over and pipe cat's output to the program. Unfortunately, this isn't an option with the limited environment. Also, there is no requirement for Expect, it just seemed like a natural solution.

Thanks!
 
Old 08-28-2012, 11:48 AM   #6
theNbomr
LQ 5k Club
 
Registered: Aug 2005
Distribution: OpenSuse, Fedora, Redhat, Debian
Posts: 5,398
Blog Entries: 2

Rep: Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908
How would you accomplish sending the file if you were not using expect? You are doing a file transfer in some form or another. To do so, you will probably need to convey the filename, and the content, obviously. Any file transfer protocol will perform things like error checking, possibly compression in transit, filename transfer, possibly even file attribute (permissions, ownership, data & timestamp, etc.).
So, either your pseudo-shell access script is already expecting the binary data to be transferred (a very weak solution, IMHO), or it must have some capability to invoke a formal file transfer protocol to receive the data. If the latter, you will need to know something about it. If the former, it must have some built-in knowledge of the file, since it would need to know when to terminate. This is particularly troublesome for binary formatted data.
It sounds to me like your expect script tried to invoke the scp client on the remote host, which is probably not what you want. You may be able to simply invoke scp from your local host, and using shared keys, transfer the file(s) in one command. No expect required. I think this is what others have tried to suggest already.

--- rod.
 
Old 08-28-2012, 06:11 PM   #7
chimpsky
LQ Newbie
 
Registered: Aug 2012
Posts: 9

Original Poster
Rep: Reputation: Disabled
Thanks for the reply, I appreciate the input. The program I mentioned is basically a wrapper for an ASCII based protocol used to manage the remote HW. If I didn’t have to proxy through the remote host and send all my commands through the “wrapper”, I would write my own script to interface directly with the hardware. For example, with PHP I could use the fsocketopen() and fwrite() functions to send the firmware to the HW. The HW will take some steps to validate the firmware data before it allows the contents to be loaded but, during the transfer, the protocol doesn’t rely on anything above TCP (I agree, not very robust).

When I mentioned SCP didn’t work, I wasn’t trying to execute SCP on the remote host through Expect. I was trying to manually copy a file to the remote host using SCP on my local host. At any rate, it wouldn’t have done me any good as I don’t have access to cat on the remote host so I would have had a whole new challenge

At this point I’ve read the contents of the file into a variable in an attempt to send the contents through Expect. Unfortunately, the contents (~10MB) appear to be larger than what my local environment will allow! Now I’m looking to recompile the Linux kernel for my local environment to increase MAX_ARG_PAGES and get around the “Argument list too long” limitation.
Thanks,
 
Old 10-17-2012, 10:09 AM   #8
jlrando
LQ Newbie
 
Registered: Oct 2012
Posts: 1

Rep: Reputation: Disabled
Hi.

I have the same problem. I need to perform some actions in a Windows server and after that I need to download a file. I am using an expect script to perform the actions via telnet. I would like to use this connection also to download the binary file created on the Windows server.

Did you succeded on performing binary content download via expdect script?

Thanks.
 
Old 10-17-2012, 05:42 PM   #9
chimpsky
LQ Newbie
 
Registered: Aug 2012
Posts: 9

Original Poster
Rep: Reputation: Disabled
Hi jlrando,
I found an acceptable workaround: redirect stdout to the PID of the SSH session. For example:

Code:
ssh user@remote_host //now open another shell or hit ~^Z
echo –e “some_command\r” > /proc/pid_of_ssh_process/fd/0
cat /path/to/binary/file > /proc/pid_of_ssh_process/fd/0
I suppose you can use a named pipe rather than redirecting output directly to stdin of the process. For example:

Code:
mkfifo mypipe
tail –f mypipe |ssh user@remote_host
echo –e “some_command\r” > mypipe
Cheers!
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
expect script using gpg decrypted file as variable mike909 Linux - Newbie 4 11-30-2017 02:59 PM
Expect script: how do i send function key F12 in an expect script alix123 Programming 4 09-01-2013 10:06 PM
[SOLVED] /usr/bin/expect : Script to check server load using both expect and bash Soji Antony Programming 1 07-28-2010 12:27 AM
Expect script fails to show file exist failure edomingox Programming 3 03-29-2009 08:11 PM
Expect script - No output to file pandersson61 Programming 4 05-23-2007 06:18 AM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 11:32 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration