0

I have to run multiple chunks of expect script inside the shell script. In between each expect scripts, I have to run shell code. Below is conceptual non-working code where, 1st chunk would SSH into a remote node, and the subsequent chunks will run some other commands on the same remote server.

#!/bin/bash

#first chunk of expect code
/usr/bin/expect - <<EOF
    global spawn_id
    spawn /bin/bash
    expect -re ".*\$"
    spawn -- "ssh   -oStrictHostKeyChecking=no -oCheckHostIP=no admin@localstack1\r"
    expect -re  ".*assword.*"
    send 'admin\r'
    expect -re ".*\$"
    interact
EOF

#running shell commands
ls -lrt


#2nd chunk of expect code

/usr/bin/expect - <<EOF
    expect -re ".*\$"
    send -- "hostname\r"
    expect -re ".*\$"
EOF

This seems to be impossible, However would like to know more from experts. unlike pexepct, here I am unable to find any way to reuse the spawned shell(passing the child object).

why?

from another program I am getting the list of commands,expected_results and timeout , so I cannot hardcode them within the expect script. Sometime there are 1 set of commands,sometimes multiple set of commands.

5
  • 1
    you are right that's a limitation when using Expect unless you write all your script in Expect/Tcl (just like you do all the things with Python when using pexpect). you can try my sexpect which is specifically designed to be used in shell scripts. Commented Jan 31, 2023 at 3:46
  • 1
    Expect is using Tcl which is also a general purpose programming language. You can use Tcl's exec to run Linux commands (e.g. your ls -lrt). Commented Jan 31, 2023 at 4:15
  • 1
    If you do it all in tcl you don't need ls at all; you can get and sort filenames directly in it. Commented Jan 31, 2023 at 4:41
  • 1
    In this case I would write the whole program in Tcl, and shell out only for those commands where you want to use bash. Commented Jan 31, 2023 at 7:42
  • Note that the first spawn of bash appears redundant, it's unrelated to the second spawn which starts ssh. Commented Jan 31, 2023 at 9:06

1 Answer 1

2

Here's an example of writing the whole thing in Expect/Tcl as suggested in the comments:

#!/usr/bin/expect

#spawn /bin/bash
#expect -re ".*\$"
spawn -- "ssh   -oStrictHostKeyChecking=no -oCheckHostIP=no admin@localstack1\r"
expect -re  ".*assword.*"
send 'admin\r'
expect -re ".*\$"
interact

#running shell commands
puts [exec ls -lrt]

expect -re ".*\$"
send -- "hostname\r"
expect -re ".*\$"

I've commented out the spawn of bash because that appears redundant.

Sign up to request clarification or add additional context in comments.

8 Comments

are you sure spawn -- "ssh -oStrictHostKeyChecking=no -oCheckHostIP=no admin@localstack1\r" would work?
Good point, that line should be changed to spawn -- ssh -oStrictHostKeyChecking=no -oCheckHostIP=no admin@localstack1.
spawn even does not support --.
You're right of course, -- should be omitted also. I suspect this line in the original script was meant to be a send.
and usually after interact returns, the spawned process would have exited so you cannot call send/expect any more.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.