using su inside of a shell script
Solution 1
Have you considered a password-less sudo instead?
Solution 2
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.
Solution 3
What you're describing might be possible with expect.
Solution 4
You can pass a command as an argument to SSH to just run that command on the server, and then exit:
ssh user@host "command to run"
This also works for a list of multiple commands:
ssh user@host "command1; command2; command3"
Or alternatively:
ssh user@host "
command1
command2
command3
"
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 either sudo
or su -c
, and force TTY allocation to SSH with the -t
switch (required if you need to enter root password):
ssh -t user@host 'su - -c "command"'
ssh -t user@host 'sudo command'
To sum it all up, one way of accomplishing what you want to do, would be:
#!/bin/bash
ssh -t [email protected] "
sudo some_command
sudo service server_instance stop
sudo some_other_command
"
Since sudo
typically remembers you authorization level for a few minutes before asking for the root password again, just prepending sudo
to all commands you need to run as root is likely the easiest way to run commands as root on the server. Adding a NOPASSWD
rule for your user in /etc/sudoers
would make the process even smoother.
I hope this helps :-)
Solution 5
No. Even if you get the password to su
, you still have to deal with the fact that su
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.
Related videos on Youtube
cmcculloh
Updated on September 17, 2022Comments
-
cmcculloh over 1 year
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?
-
gMale almost 14 years+1 good question. common problem.
-
-
Aaron Bush almost 14 yearsMost su commands accept the -c option which will take as an argument the command(s) to run. I agree that a script on the server itself is probably best vs. sending all the cmds over the ssh.
-
Mark almost 14 yearsThis is the approach I've used in the past. You can limit sudo to the required commands (start/stop the service), limiting the privileges the user has to precisely what you need. It still feels clunky, but works.
-
jabirali almost 14 yearsIf you need more information about adding that
NOPASSWD
rule, check the examples at the bottom ofman sudoers
. Also, remember to usevisudo
when editing yoursudoers
file to avoid breakage! -
cmcculloh almost 14 yearsI can't get the su - -c "command" to work. How would I supply the password for su?
-
jabirali almost 14 yearsAs for how you invoke
su -c
over SSH:ssh -t user@host 'su -lc "
<br />echo this is a test
<br />echo this is another test
<br />"
<br />'
-
jabirali almost 14 yearsReplace the
<br />
above with newlines in your script. Off-topic: Can you add newlines to ServerFault comments? That would be quite useful when posting code snippets... -
cmcculloh almost 14 yearsThis is actually what I ended up doing...
-
Theuni over 11 yearsExpect is really nice in many of those cases if you can't use regular ssh/bash scripting. However, it also becomes really clunky quickly and makes you assume "whatever you find" on the remote end. If you can change the target system or influence how it behaves at all I would recommend trying a different route first. Good point to bring it up here, though.