I'm trying to write a bash script that calls an expect script to establish a master SSH connection to be used for the remaining SSH commands in the bash script.


ControlMaster auto
ControlPath ~/.ssh/control-%r@%h:%p



expect -f /home/Dave/bin/ssh.exp

scp /home/Dave/bin/test root@

ssh root@ "echo 'Test' >> /root/test"

ssh -O exit root@


#!/usr/bin/expect -f

# Enable some diagnostic output
exp_internal 1

spawn /usr/bin/ssh -M -N root@

expect {
    -re ".*yes.*no.*" {
        exp_send "yes\r"
    -re ".*password.*" {
        exp_send "OMGSECRET\r"

$ bin/upload.sh
spawn /usr/bin/ssh -M -N root@
parent: waiting for sync byte
parent: telling child to go ahead
parent: now unsynchronized from child
spawn: returns {5212}
Gate keeper glob pattern for '.*yes.*no.*' is ''. Not usable, disabling the performance booster.
Gate keeper glob pattern for '.*password.*' is '*password*'. Activating booster.

expect: does "" (spawn_id exp4) match regular expression ".*yes.*no.*"? (No Gate, RE only) gate=yes re=no
".*password.*"? Gate "*password*"? gate=no
root@'s password:
expect: does "root@'s password: " (spawn_id exp4) match regular expression ".*yes.*no.*"? (No Gate, RE only) gate=yes re=no
".*password.*"? Gate "*password*"? gate=yes re=yes
expect: set expect_out(0,string) "root@'s password: "
expect: set expect_out(spawn_id) "exp4"
expect: set expect_out(buffer) "root@'s password: "
send: sending "OMGSECRET\r" to { exp4 }
mux_client_request_session: read from master failed: Connection reset by peer
root@'s password:
root@'s password:

The SSH connection is being established, but it craps out when I try to reuse it for the SCP command. Why?

Possible final sad edit: Alas it appears cygwin doesn't support multiplexing.

  • Are you sure that the password is correct and that the server accepts root login with a password? Does it work if you aren't using the expect script? Jan 1 '14 at 23:21
  • Where will the user be typing the password? Why not run the master ssh command in a terminal and make the user enter the password there? Jan 1 '14 at 23:22
  • Do not the password on the command line. It can be snooped by other users if they run ps at the right time. It's safe to pass the password in an environment variable ($::env(PASSWORD) in Tcl). Jan 1 '14 at 23:24
  • I'm sure the password is correct and I can log in from terminal with those credentials. The user enters the password in a web form (PHP), then the server passes the password to the bash script. Since the user doesn't see the terminal window, I can't have them enter the password there. Jan 1 '14 at 23:43
  • @Gilles I removed all mention of PHP from the question. For now, I just want to get this to work from the console. Jan 9 '14 at 6:32

Using an Expect script to send a hard-coded plaintext password is generally a Very Bad Idea. If you needs scriptable, passwordless SSH connections, it's far better to use key-pair authentication:

ssh-keygen # and then follow the prompts; don't set a passphrase
ssh-copy-id username@remote.host.example.com

After doing so, you can ssh user@remote.host.example.com without needing to key in your password.

You can still use the control connection muxing set up with the Control directives in ~/.ssh/config, and close the master connection with ssh -O exit user@remote.host.example.com.

You ought also to use ssh's utility of simply running commands remotely - once you have key-pair authentication set up, you can have:

ssh username@remote.host.exameple.com /etc/init.d/dnsmasq restart

in your script and be all set to go.

  • Who said password was hard coded? It's prompted from the user (which is btw a requirement). Jan 1 '14 at 20:00
  • In the example bash script, it's metasyntactically set on the first line after the shebang: # Set $user, $addr, $pass, $source and $dest ...
    – DopeGhoti
    Jan 1 '14 at 20:01
  • It's an argument passed to the script though. Is that okay? Jan 1 '14 at 20:01
  • It's still exposing the password in plain text to anyone who manages to read your bash script. Private keys are never set group- or world-readable and allow many layers of additional security. For example, if your key is compromised, you can remove it from the remote host's authorized-keys file and generate a new keypair without having to worry about resetting your password.
    – DopeGhoti
    Jan 1 '14 at 20:04
  • Maybe I should clarify: this script is called from an app that prompts the user for a password. I don't understand at what point it becomes plain text, unless the expect -f upload.exp "$user" "$addr" "$pass" part is logged somewhere with the actual password? Jan 1 '14 at 20:06

if this is still your question:

"The SSH connection is being established, but it craps out when I try to reuse it for the SCP command. Why?"

This happens because you are starting a seperate shell with your expect script. Your ssh session is bound to this shell and if your script ends the shell also end and your ssh session dies.

Sorry but I don't have a solution in a nutshell for this problem.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.