Как использовать su для выполнения остальной части сценария bash в качестве этого пользователя?
Я написал скрипт, который принимает в качестве аргумента строку, являющуюся конкатенацией имени пользователя и проекта. Сценарий должен переключиться (su) на имя пользователя, cd в определенный каталог на основе строки проекта.
Я в основном хочу сделать:
su $USERNAME;
cd /home/$USERNAME/$PROJECT;
svn update;
проблема в том, что как только я делаю Су... он просто ждет там. Что имеет смысл, так как поток выполнения перешел к переключению на пользователя. Как только я выхожу, то остальные вещи выполняются но это не работает как хотелось бы.
Я добавил su к команде svn, но команда не удалась (т. е. она не обновила svn в нужном каталоге).
Как написать скрипт, который позволяет пользователю переключать пользователя и вызывать svn (среди прочего)?
9 ответов:
фокус в том, чтобы использовать команду "sudo" вместо "su"
возможно, Вам придется добавить этот
username1 ALL=(username2) NOPASSWD: /path/to/svn
в ваш файл/etc / sudoers
и измените свой скрипт на:
sudo -u username2 -H sh -c "cd /home/$USERNAME/$PROJECT; svn update"
где пользователю имя_пользователя2 является пользователя, которого вы хотите выполнить команду SVN как и имя_пользователя1 является пользователя, запустившего скрипт.
Если вам нужно несколько пользователей для запуска этого сценария, используйте
%groupname
вместо username1
гораздо проще: использовать
sudo
чтобы запустить оболочку и использовать heredoc кормить его команды.#!/bin/bash whoami sudo -u someuser bash << EOF echo "In" whoami EOF echo "Out" whoami
используйте сценарий, как показано ниже, чтобы выполнить остальную часть или часть сценария под другим пользователем:
#!/bin/sh id exec sudo -u transmission /bin/sh - << eof id eof
вам нужно выполнить все команды разных пользователей как их собственный скрипт. Если это только одна или несколько команд, то inline должен работать. Если это много команд, то, вероятно, лучше переместить их в свой собственный файл.
su -c "cd /home/$USERNAME/$PROJECT ; svn update" -m "$USERNAME"
вот еще один подход, который был более удобен в моем случае (я просто хотел удалить привилегии root и сделать остальную часть моего скрипта от ограниченного пользователя): вы можете заставить скрипт перезапустить себя от правильного пользователя. Предположим, что он запускается как root изначально. Тогда это будет выглядеть так:
#!/bin/bash if [ $UID -eq 0 ]; then user= dir= shift 2 # if you need some other parameters cd "$dir" exec su "$user" "" "$@" # nothing will be executed beyond that line, # because exec replaces running process with the new one fi echo "This will be run from user $UID" ...
использовать
sudo
вместоEDIT: как отметил Дуглас, вы не можете использовать
cd
наsudo
так как это не внешний. Вы должны запустить команды в подобласти, чтобы сделатьcd
работа.sudo -u $USERNAME -H sh -c "cd ~/$PROJECT; svn update"
sudo -u $USERNAME -H cd ~/$PROJECT sudo -u $USERNAME svn update
вас могут попросить ввести пароль этого пользователя, но только один раз.
невозможно изменить пользователя в сценарии оболочки. Обходные пути с использованием sudo, описанные в других ответах, вероятно, являются вашим лучшим выбором.
Если вы достаточно безумны, чтобы запускать скрипты perl как root, вы можете сделать это с помощью
$< $( $> $)
переменные, которые содержат реальный / эффективный uid/gid, например:#!/usr/bin/perl -w $user = shift; if (!$<) { $> = getpwnam $user; $) = getgrnam $user; } else { die 'must be root to change uid'; } system('whoami');
это сработало для меня
я отделил свою "подготовку" от своего"запуска".
# Configure everything else ready to run config.vm.provision :shell, path: "provision.sh" config.vm.provision :shell, path: "start_env.sh", run: "always"
тогда в моем start_env.sh
#!/usr/bin/env bash echo "Starting Server Env" #java -jar /usr/lib/node_modules/selenium-server-standalone-jar/jar/selenium-server-standalone-2.40.0.jar & #(cd /vagrant_projects/myproj && sudo -u vagrant -H sh -c "nohup npm install 0<&- &>/dev/null &;bower install 0<&- &>/dev/null &") cd /vagrant_projects/myproj nohup grunt connect:server:keepalive 0<&- &>/dev/null & nohup apimocker -c /vagrant_projects/myproj/mock_api_data/config.json 0<&- &>/dev/null &
вдохновленный идеей от @MarSoft но я изменил строки следующим образом:
USERNAME='desireduser' COMMAND= COMMANDARGS="$(printf " %q" "${@}")" if [ $(whoami) != "$USERNAME" ]; then exec sudo -E su $USERNAME -c "/usr/bin/bash -l $COMMAND $COMMANDARGS" exit fi
я использовал
sudo
разрешить пароль меньше выполнения скрипта. Если вы хотите ввести пароль пользователя, удалитьsudo
. Если вам не нужны переменные среды, удалите-E
С судо.The
/usr/bin/bash -l
гарантирует, чтоprofile.d
скрипты выполняются для инициализации среды.