Подтвердить что ты не робот

Как использовать su для выполнения остальной части bash script в качестве этого пользователя?

Я написал script, который принимает в качестве аргумента строку, которая является конкатенацией имени пользователя и проекта. Предполагается, что script переключит (su) на имя пользователя, cd на конкретный каталог на основе строки проекта.

Я в основном хочу:

su $USERNAME;  
cd /home/$USERNAME/$PROJECT;  
svn update;  

Проблема в том, что когда я делаю su... он просто ждет там. Это имеет смысл, поскольку поток выполнения перешел к переключению на пользователя. Как только я выхожу, остальные выполняются, но он не работает по желанию.

Я добавил su к команде svn, но команда не удалась (т.е. она не обновляла svn в желаемой директории).

Как написать script, который позволяет пользователю переключать пользователя и вызывать svn (между прочим)?

4b9b3361

Ответ 1

Хитрость заключается в использовании команды "sudo" вместо "su"

Возможно, вам придется добавить этот

username1 ALL=(username2) NOPASSWD: /path/to/svn

в файл /etc/sudoers

и измените свой script на:

sudo -u username2 -H sh -c "cd /home/$USERNAME/$PROJECT; svn update" 

Где username2 является пользователем, которым вы хотите запустить команду SVN, а username1 - это пользователь, выполняющий script.

Если вам нужно несколько пользователей для запуска этого script, используйте %groupname вместо имени пользователя1

Ответ 2

Намного проще: используйте sudo для запуска оболочки и используйте heredoc для подачи команд.

#!/bin/bash
whoami
sudo -u someuser bash << EOF
echo "In"
whoami
EOF
echo "Out"
whoami

(ответ изначально на SuperUser)

Ответ 3

Используйте script следующим образом, чтобы выполнить оставшуюся часть или часть script под другим пользователем:

#!/bin/sh

id

exec sudo -u transmission /bin/sh - << eof

id

eof

Ответ 4

Вам нужно выполнить все команды разных пользователей как свои собственные script. Если это только одна или несколько команд, то встроенная строка должна работать. Если у вас много команд, лучше всего переместить их в свой файл.

su -c "cd /home/$USERNAME/$PROJECT ; svn update" -m "$USERNAME" 

Ответ 5

Вот еще один подход, который был более удобен в моем случае (я просто хотел отбросить привилегии root и выполнить оставшуюся часть моего скрипта от пользователя с ограниченными правами): вы можете сделать так, чтобы скрипт сам перезапускался от правильного пользователя. Предположим, что он изначально запускается с правами root. Тогда это будет выглядеть так:

#!/bin/bash
if [ $UID -eq 0 ]; then
  user=$1
  dir=$2
  shift 2     # if you need some other parameters
  cd "$dir"
  exec su "$user" "$0" -- "[email protected]"
  # 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"
...

Ответ 6

Используйте 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

Забастовкa >

Возможно, вас попросят ввести этот пароль пользователя, но только один раз.

Ответ 7

Невозможно изменить пользователя в оболочке script. Обходные пути, использующие 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');

Ответ 8

Это сработало для меня

Я отделил свое "обеспечение" от моего "запуска".

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

Ответ 9

Вдохновленный идеей @MarSoft, но я изменил строки следующим образом:

USERNAME='desireduser'
COMMAND=$0
COMMANDARGS="$(printf " %q" "${@}")"
if [ $(whoami) != "$USERNAME" ]; then
  exec sudo -E su $USERNAME -c "/usr/bin/bash -l $COMMAND $COMMANDARGS"
  exit
fi

Я использовал sudo чтобы позволить паролю меньше выполнять скрипт. Если вы хотите ввести пароль для пользователя, удалите sudo. Если вам не нужны переменные окружения, удалите -E из sudo.

/usr/bin/bash -l обеспечивает выполнение сценариев profile.d для инициализированной среды.