How to Execute a Series of Commands in a Bash Subshell as Another User Using Sudo

How can I execute a series of commands in a bash subshell as another user using sudo?

Run a shell inside sudo:
sudo bash -c 'whoami; whoami'

You can use any character except ' itself inside the single quotes. If you really want to have a single quote in that command, use '\'' (which technically is: end single-quote literal, literal ' character, start single-quoted literal; but effectively this is a way to inject a single quote in a single-quoted literal string).

How to execute multiple bash commands in a root sub shell?

sudo can run any command as root, not just a bash.
actually, it's suggested use is to run the commands you need rather than open a generic shell with root access.

so usually, you find something like the following in a script, giving super-user powers to only the commands that require them:

 $ cat myscript
# cmd1 doesn't require supercow powers
cmd1
# but cmd2 and cmd3 do
sudo cmd2
sudo cmd3
# cmd4 doesn't require supercow either
cmd4
$ ./myscript
$

the nice part is, that sudo will cache the authorization for you: so if you have just entered the password correctly for cmd2, it won't ask you again for cmd3.

finally, if this is much to tedious you could also run the entire script via sudo (though again it's better to keep superuser privileges to a bare minimum, so i wouldn't exactly recommend this):

 $ cat myscript
cmd1
cmd2
cmd3
cmd4
$ sudo ./myscript
$

Run a subshell as root

Expansions like command substitution will be processed by the shell before executing the actual command line:

sudo sh -c "echo $(whoami)"
foouser

Here the shell will first run whoami, as the current user, replace the expansion by it's result and then execute

sudo sh -c "echo foouser"

Expansions doesn't happen within single quotes:

sudo sh -c 'echo "$(whoami)"'
root

In this example $(whoami) won't get processed by calling shell because it appears within single quotes. $(whoami) will therefore get expanded by subshell before calling echo.

How to run two commands with sudo?

sudo can run multiple commands via a shell, for example:


$ sudo -s -- 'whoami; whoami'
root
root

Your command would be something like:


sudo -u db2inst1 -s -- "db2 connect to ttt; db2 UPDATE CONTACT SET EMAIL_ADDRESS = 'mytestaccount@gmail.com'"

If your sudo version doesn't work with semicolons with -s (apparently, it doesn't if compiled with certain options), you can use


sudo -- sh -c 'whoami; whoami'

instead, which basically does the same thing but makes you name the shell explicitly.

bash subshell command execution order with su

$ echo "hello $(echo world)"
hello world

$( ... ) runs the command inside and substitutes the collected output, i.e. the command above ends up running echo "hello world".

Similarly,

sudo -S su -c "echo a 1>&2 ; $(echo b)"

would end up running

sudo -S su -c "echo a 1>&2 ; b"

But with $(echo b 1>&2) the command writes b to stderr (and nothing to stdout), so while the shell is processing the string you see b appearing on the screen, and then the whole $( ... ) construct is replaced by nothing (because it writes nothing to stdout).

What ends up running is

sudo -S su -c "echo a 1>&2 ; " root

If all you want to do is run a command in a subshell, that's ( ... ), not $( ... ).

How to sudo su; then run command

Unless you have an unusual setup, you can't normally string su with other preceding commands like that. I would imagine it is running sudo su, then hanging in the root environment/session, because it's waiting for you to exit before preceding to the pm2 commands. Instead, I would consider something along the lines of this using the -c option:

CMD="sudo su -c 'pm2 restart 0; pm2 restart 1'"
ssh -i somepemfile.pem ubuntu@1.1.1.1 "$CMD"

As suggested in another answer, it would also probably be useful to encapsulate the $CMD variable in quotes in the ssh call.

How do I use su to execute the rest of the bash script as that user?

The trick is to use "sudo" command instead of "su"

You may need to add this

username1 ALL=(username2) NOPASSWD: /path/to/svn

to your /etc/sudoers file

and change your script to:

sudo -u username2 -H sh -c "cd /home/$USERNAME/$PROJECT; svn update" 

Where username2 is the user you want to run the SVN command as and username1 is the user running the script.

If you need multiple users to run this script, use a %groupname instead of the username1

Execute a shell script in current shell with sudo permission

What you are trying to do is impossible; your current shell is running under your regular user ID (i.e. without root the access sudo would give you), and there is no way to grant it root access. What sudo does is create a new *sub*process that runs as root. The subprocess could be just a regular program (e.g. sudo cp ... runs the cp program in a root process) or it could be a root subshell, but it cannot be the current shell.

(It's actually even more impossible than that, because the sudo command itself is executed as a subprocess of the current shell -- meaning that in a sense it's already too late for it to do anything in the "current shell", because that's not where it executes.)

bash run function with different user

You can't do that, at least not directly. (But see Richard Fletcher's answer.)

Each process runs under a particular user account. By default, that's the same account as the process that invoked it. sudo lets a process running under one account launch another process that runs under a different account.

When you invoke a shell function, it doesn't launch a new process. With some modifications, your script should give you something like:

sudo: RunStefano: command not found

In the new process created by sudo, there is no RunStefano command; the function is local to the process running the script.

You need to isolate the function into a separate executable script; you can then invoke that script via sudo.

Incidentally, you also need to change the apostrophes around /usr/bin/whoami to backticks:

echo "Ciao, `/usr/bin/whoami`"

And you should read the documentation for the sudo command; it doesn't have a -c option.



Related Topics



Leave a reply



Submit