Проблема
В скрипте bash я использую команду ...
sudo -u node bash
.. чтобы переключиться с пользователя root на пользователя, не являющегося пользователем sudo, и это не удалось.
Контекст
Я пишу скрипт provision.sh
для Vagrant, чтобы настроить сервер под управлением Ubuntu 16.04.3 со всеми пакетами, необходимыми для доставки приложения с Meteor 1.6. .
Один из необходимых шагов - установить nvm
как пользователь без полномочий root. После установки nvm
вам необходимо выйти и снова войти в систему, чтобы активировать nvm
. Поэтому я создаю пользователя не-sudo с именем meteor
и хочу переключиться на него при загрузке и установке nvm
.
Впоследствии я хочу вернуться к значению root
и сразу войти в усиление как meteor
, чтобы начать использовать nvm
для установки Node.js.
Ниже вы найдете сценарий с комментариями. Вагрант запускает этот сценарий каждый раз, когда я звоню 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
Если вы запускаете свой скрипт с правами 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"
…
Другой способ добиться того же - это документ здесь :
…
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"
…
#! /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 "" "${@}"
Если вы работаете в контейнерной среде, может быть интересен проект gosu . Он предназначен для решения проблемы, заключающейся в том, что su и sudo имеют очень странное и часто раздражающее поведение TTY и пересылки сигналов.
Несколько хороших альтернатив упоминаются в README.md проекта gosu:
chroot --userspec
, возможно, уже установлен su-exec
https://github.com/ncopa/ su-exec setpriv
из (Debian) пакета util-linux https://manpages.debian.org/buster/util-linux/setpriv.1.en.html