How can I execute a group of commands as another user in Bash?

There are already some existing questions asked here about running commands as another user. However, the question and answers focus on a single command instead of a long group of commands.

For example, consider the following script:

#!/bin/bash
set -e

root_command -p param1  # run as root

# these commands must be run as another user
command1 -p 'parameter with "quotes" inline'
command2 -p 'parameter with "quotes" inline'
command3 -p 'parameter with "quotes" inline'

There are a couple of important points to note here:

  • The final three commands must be run as another user using su or sudo. In the example there were three commands, but suppose that there were many more...

  • The commands themselves make use of single and double quotes.

The second point above prevents the use of the following syntax:

su somebody -c "command"

...since the commands themselves contain quotes.

What is the proper way to "group" the commands and run them under another user account?


Try this:

su somebody <<'EOF'
command1 -p 'parameter with "quotes" inline'
command2 -p 'parameter with "quotes" inline'
command3 -p 'parameter with "quotes" inline'
EOF

<< introduces a here-doc. The next token is the delimiter, and everything up to a line beginning with the delimiter is fed as standard input to the command. Putting the delimiter in single quotes prevents variable substitution within the here-doc.


I'm not that great with Bash-foo, so there is bound to be a more elegant way, but I've approached this problem in the past by using multiple scripts and a "driver".

E.g.,

Driver

#!/bin/bash
set -e

su root script1
su somebody script2

Script1

#!/bin/bash
set -e

root_command -p param1  # Run as root

Script2

#!/bin/bash
set -e

# These commands must be run as another user
command1 -p 'parameter with "quotes" inline'
command2 -p 'parameter with "quotes" inline'
command3 -p 'parameter with "quotes" inline'