简体   繁体   中英

Remote SSH and command execution using BASH and Expect

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, ie 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.

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.

Check this one: https://stackoverflow.com/a/23632210/524743

expect <<'END'
log_user 0
spawn sh -c {echo hello; exit 42}
expect eof
puts $expect_out(buffer)

lassign [wait] pid spawnid os_error_flag value

if {$os_error_flag == 0} {
    puts "exit status: $value"
} else {
    puts "errno: $value"
}
END

hello

exit status: 42

From the expect man page

wait [args]

delays until a spawned process (or the current process if none is named) terminates.

wait normally returns a list of four integers. The first integer is the pid of the process that was waited upon. The second integer is the corresponding spawn id. The third integer is -1 if an operating system error occurred, or 0 otherwise. If the third integer was 0, the fourth integer is the status returned by the spawned process. If the third integer was -1, the fourth integer is the value of errno set by the operating system. The global variable errorCode is also set.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM