Deepti Jain
Deepti Jain

Reputation: 1921

Changing to root user inside shell script

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

Answers (7)

anonymous
anonymous

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:

  1. Modify the sudoers file to give your user privileges to run root commands without the need for a root password.

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.

  1. 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

rubo77
rubo77

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

Igor Chubin
Igor Chubin

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

Alok Tiwari
Alok Tiwari

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

Juan T
Juan T

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

Benubird
Benubird

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

Josh
Josh

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

Related Questions