Question

I'd like to be able to pass in a long command to expect. It's a multiple command somehow. First here's my expect script


#!/usr/bin/expect -f
set timeout -1
spawn telnet xxx.xxx.xxx.xxx
expect "*?username:*"
send "someusername\r"
expect "*?assword:*"
send "somepassword\r"
# Here's the command I'd like to pass from the command prompt
set command [lindex $argv 0]
send "$command\r"
send "exit\r"

I would then run this script as so:

./expectscript "mkdir /usr/local/dir1\ncd /usr/local/dir1\ntouch testfile"

Notice that I put "\n" to initiate an enter as though I'm processing the command before moving to the next.

I know you could separate the commands with ";", but for this particular exercise, I'd like to be able have expect interpret the "\n" with a "\r" so that, expect would behave as though it were like this:

send "mkdir /usr/local/dir1\r"
send "cd /usr/local/dir1\r"
send "touch testfile\r"

The question then becomes how can expect interpret the "\n" to be "\r"? I've tried putting the "\r" in the argument instead of "\n", but that doesn't work.

Thanks for the input.

Was it helpful?

Solution

When I do a simple experiment, I find that the \n in the argument is not converted by my shell (bash) into a newline; it remains a literal. You can check this out for yourself by just using puts to print out the command line argument, like this:

puts [lindex $argv 0]

Working around this requires a little bit of work to split things. Alas, Tcl's split command does not split on multi-character sequences (it splits on many different characters at once instead) so we'll need a different approach. However, Tcllib has exactly what we need: the splitx command. With that, we do this (based on @tensaix2j's answer):

#!/usr/bin/expect -f
package require Expect;            # Good practice to put this explicitly
package require textutil::split;   # Part of Tcllib

# ... add your stuff here ...
foreach line [textutil::split::splitx [lindex $argv 0] {\\n}] {
    send "$line\r"
    # Wait for response and/or prompt?
}
# ... add your stuff here ...

If you don't have Tcllib installed and configured for use with Expect, you can also snarf the code for splitx directly out of the code (find it online here) as long as you internally acknowledge the license it's under (standard Tcl licensing rules).

OTHER TIPS

foreach cmd [ split $command \n ] {
send "$cmd\r\n"
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top