1

I have a bash script on centos7, and I need to execute some commands as different user. But it seems sudo works as expected outside function and didn't work inside bash function. I run script as ssh centos@myhost.com 'bash -s' < script.sh

test(){
    sudo -Eu root bash
    echo "inside $(whoami)"
    # other commands ...
}

test

sudo -Eu root bash
echo "outside $(whoami)"

Running this as

ssh centos@myhost.com 'bash -s' < script.sh

Prints:

outside root
inside centos

root user is given as an example for reproducibility. What is the reason behind this results? How can I execute bunch of commands inside a function as different user?

  • sudo runs a command, when the command exits you are back as the user you started with. You can't switch users inside a shell script using sudo. Also test is the name of a standard utility. It would be advisable to use another name for your function. Not writing this as a proper answer as I can't demonstrate alternative solutions (I'm on a system without sudo). – Kusalananda Feb 21 at 20:19
  • @Kusalananda But I changed user to root outside function. – tsh Feb 21 at 20:26
  • Your script will start first one interactive bash session as root (the one started from inside the function). When that exits (by you terminating it), it starts another one (outside the function). It will not produce the output that you show. – Kusalananda Feb 21 at 20:33
  • @Kusalananda My bad, forgot to mention, I execute this script through ssh. ssh centos@myhost.com 'bash -s' < script.sh this way it produces result, shown above. I've edited my question. – tsh Feb 21 at 20:38
4

Don't do this.

Getting the two lines of output in the wrong order should have been a hint that something was wrong.

When you execute your script using

ssh centos@myhost.com 'bash -s' < script.sh

the following happens:

  1. The script is passed to bash -s on the shells standard input stream.
  2. The script defines the test function and calls it.
  3. The sudo bash command in the function starts a root shell.
  4. This shell inherits the standard input stream, which is the script.
  5. The root shell continues reading the script from the point after the function call. It does this because this is where the stream is at at this point.

Now you have a root shell started from within the test function, which is executing instructions after the test call.

  1. It starts a second root shell, which inherits the standard input stream (i.e. the shell script stream).

You now have a centos shell executing a root shell, executing a root shell.

  1. The second root shell executes echo "outside $(whoami)" outputting outside root, which is the last line of the script.
  2. There is nothing more to read, so the second root shell terminates.
  3. So does the first root shell.
  4. The original bash -s shell executes echo "inside $(whoami)" (because it's part of the function that it started to execute earlier), outputting inside centos.
  5. The shell function call exits and since the rest of the script has already been read by the two root shells, the original shell has nothing more to read and terminates.

sudo is strictly for executing another command (or starting an interactive shell). The change in user is for that other command only. When the command terminates, you are back as the original user. You can not use sudo to "switch to another user" in the middle of a script and then run a part of that script as that other user (unless, of course, you deliberately write your script to be executed in the bizarre manner untangled above, but that sort of coding belongs in an obfuscated code contest).

To execute a set of commands as root in a script, you must give those commands to the sudo invocation. For example:

sudo bash -c 'echo "Now running as $USER"; echo "whoami outputs $(whoami)"'

After the sudo bash -c command exits, you are back as your original user. Always.

1

You need to execute the commands in the shell that you start with sudo.

$ f() {
sudo -Eu root bash -c whoami
}
$ f
root

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.