Super User is a question and answer site for computer enthusiasts and power users. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I am trying to automate the deploy of some .deb packages with an script. I want to execute sudo dpkg -i $myDeb.deb in a list of remote machines I can access with ssh.

I've tried to automate the command with 'expect' inside a bash script, but I am obviously doing something wrong because I get a number of different errors (depending on where I put the quotation marks, basically)

This is the function I have (will be called with something like: _remoteInstallation "myPackage115.deb" "". I know that in the remote machine, the .deb is going to be located in $HOME/Documents/:

function _remoteInstallation(){
    local retval=1
    local debToInstall=$(basename "$1")
    local remoteMachine="$2"
    spawned=$(expect -d -c "
          set timeout 1800
          spawn "/usr/bin/ssh -t borrajax@$remoteMachine /usr/bin/sudo /usr/bin/dpkg -i /home/borrajax/Documents/$debToInstall"'
          expect {
                \"Are you sure you want to continue connecting\" { send \"yes\r\"; exp_continue }
                \"password\" { send \"myPassword\r\";  exp_continue }
                \"[sudo] password\" { send \"myPassword\r\";  exp_continue }
                default { exit 1 }
    " )
    return $retval

With the quotes in the spawned area like that, I get

expect: invalid option -- 't'

If I change it to:

 spawn /usr/bin/ssh -t borrajax@$remoteMachine '/usr/bin/sudo /usr/bin/dpkg -i /home/borrajax/Documents/$debToInstall'

It looks like is trying to run the sudo dpkg command locally (first ssh(s) to '$remoteMachine' and then runs sudo dpkg locally, like two separate commands)

With this:

spawn '/usr/bin/ssh -t borrajax@$remoteMachine \'/usr/bin/sudo /usr/bin/dpkg -i /home/borrajax/Documents/$debToInstall\''

I get that couldn't execute "'/usr/bin/ssh": no such file or directory (which is not true)

... and at this point, I ran out of ideas... :-)

Any hint will be appreciated. Thank you.

share|improve this question
Also posted on unix&linux – glenn jackman Jul 3 '12 at 18:15
up vote 1 down vote accepted

What I use for a similar issue is putting all the remote-script into a file, say /usr/local/bin/ My suggestion for that in your case would be: Have a special directory where you drop the packages into -- let's call it /tmp/remoteinstall to have an example. Additionally, put the user you connect to into the /etc/suduers file, and permit it to execute sudo dpkg -i * without being prompted for a password. then would look like this:

cd /tmp/remoteinstall
sudo dpkg -i *.deb && rm -f *

Make this script owned by and chmod 744 /usr/local/bin/

Locally, your job would simply be to upload your .deb files and call the script:

cd /path/to/files
scp * user@remotemachine:/tmp/remoteinstall
ssh user@remotemachine /usr/local/bin/ would then install your packages, and afterwards empty the directory only when the install finished successfully.

In case something is missing in the $PATH, remember that neither .bashrc nor .profile are executet this way -- so you might want to either source them at the beginning of the remote script, or define the appropriate PATH there.

share|improve this answer
It turns out that the brackets in the \"[sudo]\" option were messing it up. I finally got it working with the spawn area looking like: spawn /usr/bin/ssh -t zignage@$remoteMachine \"/usr/bin/sudo /usr/bin/dpkg -i /home/zignage/Documents/$debToInstall\" and scaping the braces in sudo (\"\[sudo\]\") – BorrajaX Jul 3 '12 at 19:44
Glad to read you've got it solved! In that case your variant has the advantage to require only maintenance on one machine ;) – Izzy Jul 3 '12 at 22:05

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .