Bash – Remote SSH and command execution using BASH and Expect

bashexpectssh

I'm trying to achieve the following with a bash script:

  1. try for SSH connection, if fails, error out if SSH connection is
  2. once confirmed, execute the 'top' command and save results to file
  3. scp file back from remote server

I know the invidiual commands, which would be:
1) to check the ssh connection:

ssh -q user@ip exit

echo $?

This should return '0' on success and '255' on error.

2) to execute top and save to file would be:

top -n 1 -b > /tmp/top.out

3) scp back file from remote host

expect -c "
   set timeout 1
   spawn scp user@host:/tmp/top.out root@anotherhost:/.
   expect yes/no { send yes\r ; exp_continue }
   expect password: { send password\r }
   expect 100%
   sleep 1
   exit
"

Now putting this altogether is my problem, to be more specific:

  • I can't seem to be able to get the returned '0' and '255' values when using expect to test the SCP connection.

    • I can't seem to be able to execute the top command using expect again, i.e. this doesn't work:

    expect -c "
    set timeout 1
    spawn ssh user@host top -n 3 -b > /tmp/top.out
    expect password: { send password\r }
    sleep 1
    exit
    "

    • and therefore the 3rd bit won't work either.

Any help is appreciated. Please bear in mind that my script is a .sh script with the #!/bin/bash declaration — I cannot use #!/usr/bin/expect for various reasons.

Best Answer

Now that's ugly stuff. There are many pitfalls, probably you are not quite sure at what places you execute with a shell, or with plain argv array. Also the expect stuff is not the way that is supposed to be done, that's only brittle.

(AFAIK, expect is mainly meant to be used to communicate with modems (AT command set) and the like).

Use SSH keys for automated ssh and scp instead of passwords. Once you've done that (or even before, but then you have to enter passwords manually), launch this in your shell:

$ ssh user@server "top -n 1 -b" > /tmp/top.out

and the file will be on your local machine. (Because redirection was done locally, not yet remotely). No need to scp.

That's all there is to it.