2

My goal is to automate the following

  • From a master shell script, log in to a remote SSH session (passwordless key is already steup)
  • I then need root access, so I am using expect to log me in, i.e. send "su", expect "Password:", send "" which works.
  • Then I want to release control from expect back to the bash script that called the expect script and run various SSH commands logged in as root.

Is this possible or do I have to do everything via expect?

1
  • 1
    What's not working? Show some evidence that we can see. It's usually helpful to run expect with debugging enabled so you can see what's going on (expect -d script.exp) Commented May 25, 2016 at 18:03

1 Answer 1

2

The problem you have is that the various layers of communication have to remain in place; there's more going on than you're aware of.

Your model is this:

+------+   expect   +-----+   su   +----------------+
| bash | ---------> | ssh | -----> | remote-context | 
+------+            +-----+        +----------------+

But what's actually going on is this:

+----------------+   +----------------------+   +----------------------------+
| local terminal |   |        expect        |   |       remote terminal      |
|                |   | +------------------+ |   | +------------------------+ |
|    +------+    |   | | virtual terminal | |   | |          bash          | |
|    | bash | -----> | |                  | |   | | +--------------------+ | |
|    +------+    |   | |     +-----+      | |   | | |         su         | | |
|                |   | |     | ssh | ---------> | | | +----------------+ | | |
+----------------+   | |     +-----+      | |   | | | | remote context | | | |
                     | +------------------+ |   | | | +----------------+ | | |
                     +----------------------+   | | +--------------------+ | |
                                                | +------------------------+ |
                                                +----------------------------+

Or something like that (I've omitted most of the bits to do with the network, for example). There's a lot of layering going on, most of which you're unaware of. But because ssh is running inside expect (in order to take advantage of the automation capabilities) it means that ssh is running in a local virtual terminal controlled by expect; bash can't take control directly, and expect can't cut itself out of the loop (since bash doesn't know how to be the master side of a virtual terminal; expect and sshd do know that).

Instead, you need to either write the remainder of your code inside expect directly, or provide the code that is to be run as an argument (in some sense; perhaps pulled from a file?) that it can pass on via send.

Expect gets arguments from the argv variable, can use gets stdin to read a line of text from its caller, and open/read/close to pull in the contents of a file.


Are you aware of sudo as an alternative to su? That can be configured to allow fully password-free operation for a particular requesting user. That can be useful to allow operation of the system without exposing too large a security hole. You should also consider switching to a form of ssh that works better for automation, such as:

spawn ssh $remotehost sudo /usr/local/bin/DoTheWonderfulThing

This sort of thing, once it works, has fewer pieces that can go wrong in unexpected ways…

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

1 Comment

Thanks that's a great summary of the issue I am facing. Will give some of those suggestions a go!

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.