Pergunta

Eu escrevi um script que pega, como um argumento, uma seqüência de caracteres que é uma concatenação do nome de usuário e a um projeto.O script é suposto mudar (su) para o nome de usuário, cd para um diretório específico com base no projeto de cadeia de caracteres.

Basicamente, eu gostaria de fazer:

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

O problema é que, depois de eu fazer uma su...ele apenas aguarda lá.O que faz sentido, uma vez que o fluxo de execução passou para alternar para o usuário.Uma vez que eu sair, então o resto das coisas executar, mas ele não funciona como desejado.

Eu anexado su para o comando svn, mas a falha de comando (por exemplo,não atualização do svn no diretório desejado).

Como faço para escrever um script que permite que o usuário troque de usuário e invocar o svn (entre outras coisas)?

Foi útil?

Solução

O truque é usar o comando "sudo" em vez de "su"

Pode ser necessário adicionar isso

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

para o seu arquivo /etc /sudoers

e mude seu script para:

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

Onde o nome de usuário2 é o usuário que você deseja executar o comando svn como e o nome de usuário1 é o usuário executando o script.

Se você precisar de vários usuários para executar este script, use um %groupname em vez do nome de usuário1

Outras dicas

Muito mais simples: use sudo Para executar uma concha e usar um heredoc para alimentá -lo comandos.

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

(responda Originalmente no SuperUser)

Use um script como o seguinte para executar o restante ou parte do script sob outro usuário:

#!/bin/sh

id

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

id

eof

Você precisa executar todos os comandos do usuário diferente como seu próprio script. Se for apenas um, ou alguns comandos, então a inline deve funcionar. Se são muitos comandos, provavelmente é melhor movê -los para seu próprio arquivo.

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

Aqui está mais uma abordagem, que foi mais conveniente no meu caso (eu só queria soltar privilégios de raiz e fazer o restante do meu script do usuário restrito): você pode fazer o script se reiniciar do usuário correto. Vamos supor que seja executado como root inicialmente. Então vai ficar assim:

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

Usar sudo em vez de

EDITAR: Como Douglas apontou, você não pode usar cd dentro sudo já que não é um externo comando. Você tem que executar os comandos em uma subshell para fazer o cd trabalhar.

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

sudo -u $USERNAME -H cd ~/$PROJECT
sudo -u $USERNAME svn update

Você pode ser solicitado a inserir a senha desse usuário, mas apenas uma vez.

Não é possível mudar de utilizador dentro de um shell script.Soluções alternativas usando sudo descrito em outras respostas são, provavelmente, a sua melhor aposta.

Se você é louco o suficiente para executar os scripts perl como root, você pode fazer isso com o $< $( $> $) as variáveis que possuem real/efetiva de uid/gid, por exemplo:

#!/usr/bin/perl -w
$user = shift;
if (!$<) {
    $> = getpwnam $user;
    $) = getgrnam $user;
} else {
    die 'must be root to change uid';
}
system('whoami');

Isso funcionou para mim

Eu divida meu "provisionamento" da minha "startup".

 # Configure everything else ready to run 
  config.vm.provision :shell, path: "provision.sh"
  config.vm.provision :shell, path: "start_env.sh", run: "always"

Então no meu 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 &

Inspirado pela ideia de @MarSoft mas eu mudei as linhas como as seguintes:

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

Eu tenho usado sudo para permitir uma senha com menos de execução do script.Se você quiser digitar uma senha para o usuário, remover o sudo.Se você não precisa as variáveis de ambiente, remover -E de sudo.

O /usr/bin/bash -l garante, que o profile.d os scripts são executados por um inicializado ambiente.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top