Reputation: 73305
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?
Upvotes: 76
Views: 104371
Reputation: 1727
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'
Upvotes: 8
Reputation: 19
This script checks if the current user running the script is the desired user. If not, then the script is re-executed with the desired user.
#!/usr/bin/env bash
TOKEN_USER_X=TOKEN_USER_X
USER_X=peter # other user!
SCRIPT_PATH=$(readlink -f "$BASH_SOURCE")
if [[ "$@" != "$TOKEN_USER_X" ]]; then
###### RUN THIS PART AS the user who started the script
echo "This script is $SCRIPT_PATH"
echo -n "Current user: "
echo $USER
read -p "insert: "
echo "got $REPLY"
su - $USER_X -c "$SCRIPT_PATH $TOKEN_USER_X" # execute code below after else (marked #TOKEN_USER_X)
else
#TOKEN_USER_X -- come here only if script received one parameter TOKEN_USER_X
###### RUN THIS PART AS USER peter
echo
echo "Now this script is $SCRIPT_PATH"
echo -n "Current user: "
echo $USER
read -p "insert: "
echo "got $REPLY"
exit 0
fi
echo
echo "Back to initial user..."
echo -n "Current user: "
echo $USER
Upvotes: 0
Reputation: 782693
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.
Upvotes: 174