How do I run commands as a non-root user in a script started with root permissions?












4















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









share|improve this question

























  • 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
















4















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









share|improve this question

























  • 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














4












4








4








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









share|improve this question
















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






share|improve this question















share|improve this question













share|improve this question




share|improve this question








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 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



















  • 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

















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










2 Answers
2






active

oldest

votes


















4














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"






share|improve this answer

































    0














    #! /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 "" "${@}"





    share|improve this answer























      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
      });


      }
      });














      draft saved

      draft discarded


















      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









      4














      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"






      share|improve this answer






























        4














        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"






        share|improve this answer




























          4












          4








          4







          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"






          share|improve this answer















          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"







          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited May 9 '18 at 18:14

























          answered Nov 20 '17 at 16:21









          dessertdessert

          22.6k56398




          22.6k56398

























              0














              #! /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 "" "${@}"





              share|improve this answer




























                0














                #! /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 "" "${@}"





                share|improve this answer


























                  0












                  0








                  0







                  #! /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 "" "${@}"





                  share|improve this answer













                  #! /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 "" "${@}"






                  share|improve this answer












                  share|improve this answer



                  share|improve this answer










                  answered Jan 18 at 12:21









                  Alberto Salvia NovellaAlberto Salvia Novella

                  301112




                  301112






























                      draft saved

                      draft discarded




















































                      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.




                      draft saved


                      draft discarded














                      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





















































                      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







                      Popular posts from this blog

                      How to make a Squid Proxy server?

                      第一次世界大戦

                      Touch on Surface Book