Reputation: 1921
I have a shell script which needs non-root user account to run certain commands and then change the user to root to run the rest of the script. I am using SUSE11. I have used expect to automate the password prompt. But when I use spawn su - and the command gets executed, the prompt comes back with root and the rest of the script does not execute.
Eg.
< non-root commands>
spawn su -
<root commands>
But after su - the prompt returns back with user as root. How to execute the remaining of the script.
The sudo -S option does not help as it does not run sudo -S ifconfig command which I need to find the IP address of the machine.
I have already gone through these links but could not find a solution: Change script directory to user's homedir in a shell script
Changing unix user in a shell script
Upvotes: 26
Views: 106641
Reputation: 1
So, from what I understand, you need to execute a set of commands in root privileges and also to automate the root password input.
You can't really change the user account using a shell script(or there might be a way that i dont know) but if it's just executing a set of commands, you can use EOF as mentioned in the other answers.
As for automating the root password input, there are some ways but both are pretty unsafe:
Edit the /etc/sudoers file using editors such as vi Add the following in the end of file
<username> ALL=(ALL) NOPASSWD: ALL
This removes the need for sudo password to <username>
user.
This is generally not recommended as it exposes your root password.
you can use:
echo "{{root_pw}}" | sudo <command>
which is essentially just passing root password via echo, but atleast the script won't stop the execution for user input. NOTE: This is very unsafe if you are sharing the file.
Upvotes: 0
Reputation: 20875
You can use this function that will call the script again as root passing the first argument to the new call:
A=$1
run_with_sudo() {
local prompt
prompt=$(sudo -nv 2>&1)
if [ $? -eq 0 ]; then
# the current user has sudo and the password is already set
if [ "$(whoami)" != "root" ]; then
# restart script as root
exec sudo su - <<EOF
"$0" "$A"
EOF
exit
fi
elif echo $prompt | grep -q '^sudo:'; then
echo "the current user has sudo but needs the password entered"
return 1
else
echo "the current user has no sudo rights"
return 1
fi
}
note that "$0" may not be what you think it is]
Upvotes: 0
Reputation: 64613
sudo
will work here but you need to change your script a little bit:
$ cat 1.sh
id
sudo -s <<EOF
echo Now i am root
id
echo "yes!"
EOF
$ bash 1.sh
uid=1000(igor) gid=1000(igor) groups=1000(igor),29(audio),44(video),124(fuse)
Now i am root
uid=0(root) gid=0(root) groups=0(root)
yes!
You need to run your command in <<EOF
block and give the block to sudo
.
If you want, you can use su
, of course. But you need to run it using expect/pexpect
that will enter password for you.
But even in case you could manage to enter the password automatically (or switch it off) this construction would not work:
user-command
su
root-command
In this case root-command
will be executed with user, not with root privileges, because it will be executed after su
will be finished (su
opens a new shell, not changes uid of the current shell). You can use the same trick here of course:
su -c 'sh -s' <<EOF
# list of root commands
EOF
But now you have the same as with sudo
.
Upvotes: 29
Reputation: 364
Also, note that if you are changing to "root" user inside a shell script like below one, few Linux utilities like awk for data extraction or defining even a simple shell variable etc will behave weirdly.
To resolve this simply quote the whole document by using <<'EOF' in place of EOF.
sudo -i <<'EOF'
ls
echo "I am root now"
EOF
Upvotes: 3
Reputation: 61
Short version: create a block to enclose all commands to be run as root.
For example, I created a script to run a command from a root subdirectory, the segment goes like this:
sudo su - <<EOF
cd rootSubFolder/subfolder
./commandtoRun
EOF
Upvotes: 6
Reputation: 19547
There is an easy way to do it without a second script. Just put this at the start of your file:
if [ "$(whoami)" != "root" ]
then
sudo su -s "$0"
exit
fi
Then it will automatically run itself as root. Of course, this assumes that you can sudo su
without having to provide a password - but that's out of scope of this answer; see one of the other questions about using sudo in shell scripts for how to do that.
Upvotes: 13
Reputation: 296
The easiest way to do that would be to create a least two scripts.
The first one should call the second one with root privileges. So every command you execute in the second script would be executed as root.
For example:
runasroot.sh
sudo su-c'./scriptname.sh'
scriptname.sh
apt-get install mysql-server-5.5
or whatever you need.
Upvotes: 2