How do I run commands as a non-root user in a script started with root permissions?
The problem
In a bash script, I am using the command...
sudo -u node bash
.. to switch from root to a non-sudo user, and this is failing.
The context
I am writing a provision.sh script for Vagrant, to set up a server running Ubuntu 16.04.3 with all the packages required to deliver an app with Meteor 1.6.
One required step is to install nvm as a non-root user. After nvm is installed, you need to log out and log back in again in order to activate nvm. I therefore create a non-sudo user named meteor, and want to switch to that when I download and install nvm.
Subsequently, I want to switch back to being root and log in gain immediately as meteor, in order to start using nvm to install Node.js.
You'll find a heavily commented script below. Vagrant runs this script each time I call vagrant reload --provision.
What command should I be using instead of sudo -u node bash?
echo "# whoami" && whoami && echo "^^^^ root expected"
echo "As root, create non-sudo user meteor:"
pass=$(perl -e 'print crypt($ARGV[0], "password")' $password)
useradd -m -p $pass meteor
echo "User meteor created. ls -al /home/meteor:"
ls -al /home/meteor
echo "Install curl as root:"
apt-get install -y curl
echo "Trying sudo -u meteor bash"
sudo -u meteor bash #### THIS IS THE LINE THAT FAILS ###
echo "$ whoami" && whoami && echo "^^^^^^ meteor expected"
curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.33.6/install.sh | bash
echo "ls -al /home/meteor/.nvm # should be populated"
ls -al /home/meteor/.nvm
echo "ls -al /root/.nvm # should not exist"
ls -al /root/.nvm
echo "command -v nvm will fail silently until we log out and back in again"
#command -v nvm
exit
#### Because the script is still running as root, it halts here ####
echo "# whoami" && whoami && echo "^^^^ should be root"
sudo -u meteor bash
echo "$ whoami" && whoami && echo "^^^^^^ should be meteor"
echo "command -v nvm should work now"
command -v nvm
bash scripts sudo
add a comment |
The problem
In a bash script, I am using the command...
sudo -u node bash
.. to switch from root to a non-sudo user, and this is failing.
The context
I am writing a provision.sh script for Vagrant, to set up a server running Ubuntu 16.04.3 with all the packages required to deliver an app with Meteor 1.6.
One required step is to install nvm as a non-root user. After nvm is installed, you need to log out and log back in again in order to activate nvm. I therefore create a non-sudo user named meteor, and want to switch to that when I download and install nvm.
Subsequently, I want to switch back to being root and log in gain immediately as meteor, in order to start using nvm to install Node.js.
You'll find a heavily commented script below. Vagrant runs this script each time I call vagrant reload --provision.
What command should I be using instead of sudo -u node bash?
echo "# whoami" && whoami && echo "^^^^ root expected"
echo "As root, create non-sudo user meteor:"
pass=$(perl -e 'print crypt($ARGV[0], "password")' $password)
useradd -m -p $pass meteor
echo "User meteor created. ls -al /home/meteor:"
ls -al /home/meteor
echo "Install curl as root:"
apt-get install -y curl
echo "Trying sudo -u meteor bash"
sudo -u meteor bash #### THIS IS THE LINE THAT FAILS ###
echo "$ whoami" && whoami && echo "^^^^^^ meteor expected"
curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.33.6/install.sh | bash
echo "ls -al /home/meteor/.nvm # should be populated"
ls -al /home/meteor/.nvm
echo "ls -al /root/.nvm # should not exist"
ls -al /root/.nvm
echo "command -v nvm will fail silently until we log out and back in again"
#command -v nvm
exit
#### Because the script is still running as root, it halts here ####
echo "# whoami" && whoami && echo "^^^^ should be root"
sudo -u meteor bash
echo "$ whoami" && whoami && echo "^^^^^^ should be meteor"
echo "command -v nvm should work now"
command -v nvm
bash scripts sudo
You'll have to extract the parts into another script and call sudo on that, or call each command with sudo (in this case that's only the bash after the curl).sudo -u meteor bashsimply starts bash as meteor, it can't simply take over the rest of the script.
– muru
Nov 20 '17 at 16:08
Related, maybe a duplicate? Best practices on using sudo in a bash script
– wjandrea
Nov 22 '17 at 20:59
add a comment |
The problem
In a bash script, I am using the command...
sudo -u node bash
.. to switch from root to a non-sudo user, and this is failing.
The context
I am writing a provision.sh script for Vagrant, to set up a server running Ubuntu 16.04.3 with all the packages required to deliver an app with Meteor 1.6.
One required step is to install nvm as a non-root user. After nvm is installed, you need to log out and log back in again in order to activate nvm. I therefore create a non-sudo user named meteor, and want to switch to that when I download and install nvm.
Subsequently, I want to switch back to being root and log in gain immediately as meteor, in order to start using nvm to install Node.js.
You'll find a heavily commented script below. Vagrant runs this script each time I call vagrant reload --provision.
What command should I be using instead of sudo -u node bash?
echo "# whoami" && whoami && echo "^^^^ root expected"
echo "As root, create non-sudo user meteor:"
pass=$(perl -e 'print crypt($ARGV[0], "password")' $password)
useradd -m -p $pass meteor
echo "User meteor created. ls -al /home/meteor:"
ls -al /home/meteor
echo "Install curl as root:"
apt-get install -y curl
echo "Trying sudo -u meteor bash"
sudo -u meteor bash #### THIS IS THE LINE THAT FAILS ###
echo "$ whoami" && whoami && echo "^^^^^^ meteor expected"
curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.33.6/install.sh | bash
echo "ls -al /home/meteor/.nvm # should be populated"
ls -al /home/meteor/.nvm
echo "ls -al /root/.nvm # should not exist"
ls -al /root/.nvm
echo "command -v nvm will fail silently until we log out and back in again"
#command -v nvm
exit
#### Because the script is still running as root, it halts here ####
echo "# whoami" && whoami && echo "^^^^ should be root"
sudo -u meteor bash
echo "$ whoami" && whoami && echo "^^^^^^ should be meteor"
echo "command -v nvm should work now"
command -v nvm
bash scripts sudo
The problem
In a bash script, I am using the command...
sudo -u node bash
.. to switch from root to a non-sudo user, and this is failing.
The context
I am writing a provision.sh script for Vagrant, to set up a server running Ubuntu 16.04.3 with all the packages required to deliver an app with Meteor 1.6.
One required step is to install nvm as a non-root user. After nvm is installed, you need to log out and log back in again in order to activate nvm. I therefore create a non-sudo user named meteor, and want to switch to that when I download and install nvm.
Subsequently, I want to switch back to being root and log in gain immediately as meteor, in order to start using nvm to install Node.js.
You'll find a heavily commented script below. Vagrant runs this script each time I call vagrant reload --provision.
What command should I be using instead of sudo -u node bash?
echo "# whoami" && whoami && echo "^^^^ root expected"
echo "As root, create non-sudo user meteor:"
pass=$(perl -e 'print crypt($ARGV[0], "password")' $password)
useradd -m -p $pass meteor
echo "User meteor created. ls -al /home/meteor:"
ls -al /home/meteor
echo "Install curl as root:"
apt-get install -y curl
echo "Trying sudo -u meteor bash"
sudo -u meteor bash #### THIS IS THE LINE THAT FAILS ###
echo "$ whoami" && whoami && echo "^^^^^^ meteor expected"
curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.33.6/install.sh | bash
echo "ls -al /home/meteor/.nvm # should be populated"
ls -al /home/meteor/.nvm
echo "ls -al /root/.nvm # should not exist"
ls -al /root/.nvm
echo "command -v nvm will fail silently until we log out and back in again"
#command -v nvm
exit
#### Because the script is still running as root, it halts here ####
echo "# whoami" && whoami && echo "^^^^ should be root"
sudo -u meteor bash
echo "$ whoami" && whoami && echo "^^^^^^ should be meteor"
echo "command -v nvm should work now"
command -v nvm
bash scripts sudo
bash scripts sudo
edited Nov 22 '17 at 19:44
dessert
22.6k56398
22.6k56398
asked Nov 20 '17 at 15:43
James NewtonJames Newton
287217
287217
You'll have to extract the parts into another script and call sudo on that, or call each command with sudo (in this case that's only the bash after the curl).sudo -u meteor bashsimply starts bash as meteor, it can't simply take over the rest of the script.
– muru
Nov 20 '17 at 16:08
Related, maybe a duplicate? Best practices on using sudo in a bash script
– wjandrea
Nov 22 '17 at 20:59
add a comment |
You'll have to extract the parts into another script and call sudo on that, or call each command with sudo (in this case that's only the bash after the curl).sudo -u meteor bashsimply starts bash as meteor, it can't simply take over the rest of the script.
– muru
Nov 20 '17 at 16:08
Related, maybe a duplicate? Best practices on using sudo in a bash script
– wjandrea
Nov 22 '17 at 20:59
You'll have to extract the parts into another script and call sudo on that, or call each command with sudo (in this case that's only the bash after the curl).
sudo -u meteor bash simply starts bash as meteor, it can't simply take over the rest of the script.– muru
Nov 20 '17 at 16:08
You'll have to extract the parts into another script and call sudo on that, or call each command with sudo (in this case that's only the bash after the curl).
sudo -u meteor bash simply starts bash as meteor, it can't simply take over the rest of the script.– muru
Nov 20 '17 at 16:08
Related, maybe a duplicate? Best practices on using sudo in a bash script
– wjandrea
Nov 22 '17 at 20:59
Related, maybe a duplicate? Best practices on using sudo in a bash script
– wjandrea
Nov 22 '17 at 20:59
add a comment |
2 Answers
2
active
oldest
votes
If you start your script with root permissions but need to run certain commands as a specific non-root user you can use sudo with the -u option to either run a single command with e.g.
sudo -u USERNAME whoami # outputs USERNAME's user name
or start a subshell and run your commands in it, e.g.:
sudo -u USERNAME bash -c 'whoami;echo $USER' # outputs USERNAME's user name twice
The line in your script doesn't fail actually, you just run only bash as user meteor, and as bash has nothing to do it just exits and the original root shell runs the rest of the script. What you actually want to do (I suppose) is:
…
echo "Trying sudo -u meteor bash"
sudo -u meteor bash -c '
echo "$ whoami" && whoami && echo "^^^^^^ meteor expected"
curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.33.6/install.sh |
bash
'
echo "ls -al /home/meteor/.nvm # should be populated"
…
Another way to achieve the same is a here document:
…
echo "Trying sudo -u meteor bash"
sudo -u meteor bash <<EOF
echo "$ whoami" && whoami && echo "^^^^^^ meteor expected"
curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.33.6/install.sh |
bash
EOF
echo "ls -al /home/meteor/.nvm # should be populated"
…
add a comment |
#! /bin/bash
# (GPL3+) Alberto Salvia Novella (es20490446e)
execute () {
function="${1}"
command="${2}"
error=$(eval "${command}" 2>&1 >"/dev/null")
if [ ${?} -ne 0 ]; then
echo "${function}: $error"
exit 1
fi
}
executeAsNonAdmin () {
function="${1}"
command="${2}"
eval setPasswordAsker="SUDO_ASKPASS=/usr/libexec/openssh/ssh-askpass"
run="runuser ${SUDO_USER} --session-command="${setPasswordAsker}" --command="${command}""
execute "${function}" "${run}"
}
executeAsNonAdmin "" "${@}"
add a comment |
Your Answer
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "89"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2faskubuntu.com%2fquestions%2f978451%2fhow-do-i-run-commands-as-a-non-root-user-in-a-script-started-with-root-permissio%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
If you start your script with root permissions but need to run certain commands as a specific non-root user you can use sudo with the -u option to either run a single command with e.g.
sudo -u USERNAME whoami # outputs USERNAME's user name
or start a subshell and run your commands in it, e.g.:
sudo -u USERNAME bash -c 'whoami;echo $USER' # outputs USERNAME's user name twice
The line in your script doesn't fail actually, you just run only bash as user meteor, and as bash has nothing to do it just exits and the original root shell runs the rest of the script. What you actually want to do (I suppose) is:
…
echo "Trying sudo -u meteor bash"
sudo -u meteor bash -c '
echo "$ whoami" && whoami && echo "^^^^^^ meteor expected"
curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.33.6/install.sh |
bash
'
echo "ls -al /home/meteor/.nvm # should be populated"
…
Another way to achieve the same is a here document:
…
echo "Trying sudo -u meteor bash"
sudo -u meteor bash <<EOF
echo "$ whoami" && whoami && echo "^^^^^^ meteor expected"
curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.33.6/install.sh |
bash
EOF
echo "ls -al /home/meteor/.nvm # should be populated"
…
add a comment |
If you start your script with root permissions but need to run certain commands as a specific non-root user you can use sudo with the -u option to either run a single command with e.g.
sudo -u USERNAME whoami # outputs USERNAME's user name
or start a subshell and run your commands in it, e.g.:
sudo -u USERNAME bash -c 'whoami;echo $USER' # outputs USERNAME's user name twice
The line in your script doesn't fail actually, you just run only bash as user meteor, and as bash has nothing to do it just exits and the original root shell runs the rest of the script. What you actually want to do (I suppose) is:
…
echo "Trying sudo -u meteor bash"
sudo -u meteor bash -c '
echo "$ whoami" && whoami && echo "^^^^^^ meteor expected"
curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.33.6/install.sh |
bash
'
echo "ls -al /home/meteor/.nvm # should be populated"
…
Another way to achieve the same is a here document:
…
echo "Trying sudo -u meteor bash"
sudo -u meteor bash <<EOF
echo "$ whoami" && whoami && echo "^^^^^^ meteor expected"
curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.33.6/install.sh |
bash
EOF
echo "ls -al /home/meteor/.nvm # should be populated"
…
add a comment |
If you start your script with root permissions but need to run certain commands as a specific non-root user you can use sudo with the -u option to either run a single command with e.g.
sudo -u USERNAME whoami # outputs USERNAME's user name
or start a subshell and run your commands in it, e.g.:
sudo -u USERNAME bash -c 'whoami;echo $USER' # outputs USERNAME's user name twice
The line in your script doesn't fail actually, you just run only bash as user meteor, and as bash has nothing to do it just exits and the original root shell runs the rest of the script. What you actually want to do (I suppose) is:
…
echo "Trying sudo -u meteor bash"
sudo -u meteor bash -c '
echo "$ whoami" && whoami && echo "^^^^^^ meteor expected"
curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.33.6/install.sh |
bash
'
echo "ls -al /home/meteor/.nvm # should be populated"
…
Another way to achieve the same is a here document:
…
echo "Trying sudo -u meteor bash"
sudo -u meteor bash <<EOF
echo "$ whoami" && whoami && echo "^^^^^^ meteor expected"
curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.33.6/install.sh |
bash
EOF
echo "ls -al /home/meteor/.nvm # should be populated"
…
If you start your script with root permissions but need to run certain commands as a specific non-root user you can use sudo with the -u option to either run a single command with e.g.
sudo -u USERNAME whoami # outputs USERNAME's user name
or start a subshell and run your commands in it, e.g.:
sudo -u USERNAME bash -c 'whoami;echo $USER' # outputs USERNAME's user name twice
The line in your script doesn't fail actually, you just run only bash as user meteor, and as bash has nothing to do it just exits and the original root shell runs the rest of the script. What you actually want to do (I suppose) is:
…
echo "Trying sudo -u meteor bash"
sudo -u meteor bash -c '
echo "$ whoami" && whoami && echo "^^^^^^ meteor expected"
curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.33.6/install.sh |
bash
'
echo "ls -al /home/meteor/.nvm # should be populated"
…
Another way to achieve the same is a here document:
…
echo "Trying sudo -u meteor bash"
sudo -u meteor bash <<EOF
echo "$ whoami" && whoami && echo "^^^^^^ meteor expected"
curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.33.6/install.sh |
bash
EOF
echo "ls -al /home/meteor/.nvm # should be populated"
…
edited May 9 '18 at 18:14
answered Nov 20 '17 at 16:21
dessertdessert
22.6k56398
22.6k56398
add a comment |
add a comment |
#! /bin/bash
# (GPL3+) Alberto Salvia Novella (es20490446e)
execute () {
function="${1}"
command="${2}"
error=$(eval "${command}" 2>&1 >"/dev/null")
if [ ${?} -ne 0 ]; then
echo "${function}: $error"
exit 1
fi
}
executeAsNonAdmin () {
function="${1}"
command="${2}"
eval setPasswordAsker="SUDO_ASKPASS=/usr/libexec/openssh/ssh-askpass"
run="runuser ${SUDO_USER} --session-command="${setPasswordAsker}" --command="${command}""
execute "${function}" "${run}"
}
executeAsNonAdmin "" "${@}"
add a comment |
#! /bin/bash
# (GPL3+) Alberto Salvia Novella (es20490446e)
execute () {
function="${1}"
command="${2}"
error=$(eval "${command}" 2>&1 >"/dev/null")
if [ ${?} -ne 0 ]; then
echo "${function}: $error"
exit 1
fi
}
executeAsNonAdmin () {
function="${1}"
command="${2}"
eval setPasswordAsker="SUDO_ASKPASS=/usr/libexec/openssh/ssh-askpass"
run="runuser ${SUDO_USER} --session-command="${setPasswordAsker}" --command="${command}""
execute "${function}" "${run}"
}
executeAsNonAdmin "" "${@}"
add a comment |
#! /bin/bash
# (GPL3+) Alberto Salvia Novella (es20490446e)
execute () {
function="${1}"
command="${2}"
error=$(eval "${command}" 2>&1 >"/dev/null")
if [ ${?} -ne 0 ]; then
echo "${function}: $error"
exit 1
fi
}
executeAsNonAdmin () {
function="${1}"
command="${2}"
eval setPasswordAsker="SUDO_ASKPASS=/usr/libexec/openssh/ssh-askpass"
run="runuser ${SUDO_USER} --session-command="${setPasswordAsker}" --command="${command}""
execute "${function}" "${run}"
}
executeAsNonAdmin "" "${@}"
#! /bin/bash
# (GPL3+) Alberto Salvia Novella (es20490446e)
execute () {
function="${1}"
command="${2}"
error=$(eval "${command}" 2>&1 >"/dev/null")
if [ ${?} -ne 0 ]; then
echo "${function}: $error"
exit 1
fi
}
executeAsNonAdmin () {
function="${1}"
command="${2}"
eval setPasswordAsker="SUDO_ASKPASS=/usr/libexec/openssh/ssh-askpass"
run="runuser ${SUDO_USER} --session-command="${setPasswordAsker}" --command="${command}""
execute "${function}" "${run}"
}
executeAsNonAdmin "" "${@}"
answered Jan 18 at 12:21
Alberto Salvia NovellaAlberto Salvia Novella
301112
301112
add a comment |
add a comment |
Thanks for contributing an answer to Ask Ubuntu!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2faskubuntu.com%2fquestions%2f978451%2fhow-do-i-run-commands-as-a-non-root-user-in-a-script-started-with-root-permissio%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
You'll have to extract the parts into another script and call sudo on that, or call each command with sudo (in this case that's only the bash after the curl).
sudo -u meteor bashsimply starts bash as meteor, it can't simply take over the rest of the script.– muru
Nov 20 '17 at 16:08
Related, maybe a duplicate? Best practices on using sudo in a bash script
– wjandrea
Nov 22 '17 at 20:59