web-dev-qa-db-ja.com

root権限で開始されたスクリプトで非rootユーザーとしてコマンドを実行するにはどうすればよいですか?

問題
bashスクリプトでは、次のコマンドを使用しています...

Sudo -u node bash

.. rootから非Sudoユーザーに切り替えるため、これは失敗します。

コンテキスト
Vagrant用のprovision.shスクリプトを作成して、Meteor 1.6でアプリを配信するために必要なすべてのパッケージでUbuntu 16.04.3を実行するサーバーをセットアップしています。

必要な手順の1つは、nvmを非rootユーザーとしてインストールすることです。 nvmをインストールした後、nvmをアクティブにするには、ログアウトしてから再度ログインする必要があります。そのため、meteorという名前の非Sudoユーザーを作成し、nvmをダウンロードしてインストールするときにそのユーザーに切り替えたいと思います。

その後、rootに戻り、meteorとしてすぐにログインし、nvmを使用してNode.jsをインストールします。

以下に、コメントの多いスクリプトがあります。 Vagrantは、vagrant reload --provisionを呼び出すたびにこのスクリプトを実行します。

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
5
James Newton

Root権限でスクリプトを起動したが、特定のコマンドを特定の非rootユーザーとして実行する必要がある場合は、Sudo-uオプションとともに使用して、単一のコマンドを実行できます。

Sudo -u USERNAME whoami # outputs USERNAME's user name

または、サブシェルを起動してコマンドを実行します。例:

Sudo -u USERNAME bash -c 'whoami;echo $USER' # outputs USERNAME's user name twice

スクリプトの行は実際には失敗せず、ユーザーbashとしてmeteorのみを実行し、bashには何も実行されず、元のルートシェルが残りを実行します。スクリプトの。あなたが実際にやりたいことは(私が思うに)です:

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

同じことを達成する別の方法は、 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"
…
5
dessert
#! /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 "" "${@}"