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
orsudo
. 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'