I'm automating a deploy process and I want to be able to just call one .sh file on my machine, have it do my build and upload the .zip to the server and then do a bunch of stuff on the server. One of the things I need to do requires me to be root. So, What I want to do is this:
ssh [email protected] <<END_SCRIPT
su -
#password... somehow...
#stop jboss
service server_instance stop
#a bunch of stuff here
#all done!
exit
END_SCRIPT
Is this even possible?
Have you considered a password-less sudo instead?
Instead of su, use sudo with the NOPASSWD set in sudoers for appropriate command(s). You'll want to make the allowed command set as limited as possible. Having it call run a script for the root commands may be the cleanest way and by far easiest to make secure if you are unfamiliar with sudoer file syntax. For commands/scripts that require the full environment to be loaded,
sudo su - -c command
works although may be overkill.What you're describing might be possible with expect.
You can pass a command as an argument to SSH to just run that command on the server, and then exit:
This also works for a list of multiple commands:
Or alternatively:
As other users have pointed out before me, running
su
on the server will launch a new shell instead of executing subsequent commands in the script as root. What you need to do, is to use eithersudo
orsu -c
, and force TTY allocation to SSH with the-t
switch (required if you need to enter root password):To sum it all up, one way of accomplishing what you want to do, would be:
Since
sudo
typically remembers you authorization level for a few minutes before asking for the root password again, just prependingsudo
to all commands you need to run as root is likely the easiest way to run commands as root on the server. Adding aNOPASSWD
rule for your user in/etc/sudoers
would make the process even smoother.I hope this helps :-)
No. Even if you get the password to
su
, you still have to deal with the fact thatsu
will open a new shell, which means that your further commands will not be passed to it. You will need to write a script for the root operations along with a helper executable that can invoke it with the appropriate privileges.Write an expect script. I know you've already found an answer for this, but this might be helpful if you have to login to a bunch of servers that require interactive password entry.
It's a language based off of TCL, so it might be a bit weird compared to plain old shell scripts. But it handles automation of text input and, you guessed it, "expects" certain bits of output before entering in any sort of automated password entry or escalation of privileges.
Here's a good link as a guide: http://bash.cyberciti.biz/security/expect-ssh-login-script/
Just in case the site goes down:
I know this is a bit late but I would personally use Net::SSH::Expect, available from CPAN.
http://search.cpan.org/~bnegrao/Net-SSH-Expect-1.09/lib/Net/SSH/Expect.pod
You can use 'ssh example.com su -lc "$cmd"'.
When command contains options, you need to quote it, otherwise "su" might eat them ("su: invalid option -- 'A').