Quais arquivos são originados ao usar su -c?

7

Contexto

Você está trabalhando no Ubuntu LTS 14.04. Você está logado como usuário root. Você executa o seguinte comando:

exec su simple_user -c "/bin/bash /etc/init.d/simple_user_service"

Para que o "simple_user_service" seja iniciado com privilégios "simple_user" e não privilégios de root.

Pergunta

Parece que "exec su simple_user -c" não origina .bashrc nem .profile nem qualquer outro arquivo normalmente originado para um novo terminal de shell interativo. Eu confirmei isso adicionando esta linha no arquivo .bashr do simple_user:

export TEST="Hello"

Em seguida, no meu script de inicialização "simple_user_service":

#!/bin/bash
### BEGIN INIT INFO
# Provides:             test_script
# X-Interactive:        true
# Short-Description:    Test script
### END INIT INFO

echo $TEST

Quando executo o script, nada é impresso, mas se eu executar os seguintes comandos:

su simple_user
echo $TEST
> Hello

A variável TEST é definida e impressa corretamente.

Então, eu queria saber: o comando "exec su simple_user -c" fornece qualquer arquivo profile_user / bashrc do simple_user? Se assim for, há uma maneira de saber quais?

Muito obrigado pela sua ajuda!

[Editar - 2 horas depois]

Graças à resposta que recebi, entendi com mais precisão as instruções do 'homem bash'. Eu encontrei isto:

   When bash is started non-interactively, to run a shell script, for example, it looks for the variable BASH_ENV in the environment, expands its value if it  appears  there,  and
   uses the expanded value as the name of a file to read and execute.  Bash behaves as if the following command were executed:
          if [ -n "$BASH_ENV" ]; then . "$BASH_ENV"; fi
   but the value of the PATH variable is not used to search for the file name.

É realmente interessante como você pode definir BASH_ENV para um arquivo que executa comandos específicos cada vez que você usa "su simple_user -c" sem precisar carregar toda a lógica interativa.

Então, antes de executar su simple_user -c , você pode simplesmente fazer:

export BASH_ENV=~/.bash_script

E defina as coisas no seu arquivo simple_user .bash_script, como:

export TEST="Hello"

Então, quando eu executo o script "simple_user_service", "Hello" é impresso corretamente.

Foi muito útil para mim, pois precisava disso para carregar todo o ambiente "rvm" (ruby) para executar um script específico.

Quer saber mais?

Por que todo esse problema?

Porque eu instalei o ruby god: link para monitore este script específico (um trabalho atrasado).

Estou usando o "rvm" para gerenciar diferentes rubis.

E o script automaticamente descarta privilégios, se necessário, executando exec su application_user -c "/bin/bash application_script"

Como deus precisa ser executado com privilégios de root e rvm é carregado apenas em arquivos .bashrc / .profile, eu precisava de uma maneira de carregar adequadamente o ambiente rvm no meu script. Eu poderia simplesmente adicionar o comando rvm load no script, mas meu script teria sido dependente do ambiente e isso não era aceitável.

Então, adicionei isso ao meu script antes que os privilégios fossem descartados:

if [ -e "config/BASH_ENV" ]; then
  export BASH_ENV=$(cat config/BASH_ENV)
fi

Graças a isso eu posso carregar rvm no arquivo que eu configurei no arquivo config / BASH_ENV. Por exemplo, poderia ser:

# In config/BASH_ENV file of your rails app:
export BASH_ENV="~/.bash_script"

# In /home/simple_user/.bash_script 
[[ -s "/etc/profile.d/rvm.sh" ]] && . "/etc/profile.d/rvm.sh" # Load RVM function

Então, meu script e meu deus funcionam como esperado.

Eu não expliquei todas essas coisas antes de obter respostas para que os leitores pudessem se concentrar na questão real.

Mas como recebi uma boa resposta e encontrei uma boa solução graças a isso, escrevi esta edição para que ela pudesse ser útil para outras pessoas.

Obrigado novamente!

    
por Kulgar 13.10.2015 / 12:35

1 resposta

9

Quando você faz:

su some_user -c 'some_command'    

O some_command será executado como:

bash -c 'some_command'

Assumindo que bash seja o shell de some_user definido em /etc/passwd .

Agora, quando você executa bash -c 'some_command' , basicamente gera uma sessão não interativa (e, é claro, sem login ) de bash . Como nenhum arquivo é originado pelo shell no modo não interativo, portanto, nenhum arquivo está sendo lido com expectativa.

Observe que ~/.profile é originado em um login, sessão interativa de bash e ~/.bashrc é originada em uma sessão interativa sem logon de bash . Observe também que as fontes do Ubuntu ~/.bashrc de ~/.profile .

Verifique a seção INVOCATION de man bash para ter mais ideia.

    
por heemayl 13.10.2015 / 13:04