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

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

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 lançado com privilégios "simple_user" e não privilégios de root.

Pergunta

Parece que "exec su simple_user -c" não fornece .bashrc nem .profile nem qualquer outro arquivo de origem normal para o novo terminal shell interativo. Confirmei isso adicionando esta linha no arquivo simple_user .bashrc:

export TEST="Hello"

Então, 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 está definida e impressa corretamente.

Então, eu queria saber: o comando "exec su simple_user -c" origina algum arquivo de perfil/bashrc de simple_user? Se sim, existe uma maneira de saber quais?

Muito obrigado por sua ajuda!

[Editar - 2 horas depois]

Graças à resposta que recebi, entendi com mais precisão as instruções do 'man bash'. Eu achei 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 porque 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 a lógica interativa completa.

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

export BASH_ENV=~/.bash_script

E defina coisas em seu arquivo simple_user .bash_script, como:

export TEST="Hello"

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

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

Quer saber mais?

Por que todo esse problema?

Porque eu instalei Ruby God:http://godrb.com/para monitorar este script específico (um trabalho atrasado).

E estou usando "rvm" para gerenciar diferentes rubis.

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

Como god precisa ser executado com privilégios de root e o rvm só é carregado em arquivos .bashrc/.profile, eu precisava de uma maneira de carregar corretamente o ambiente rvm em meu script. Eu poderia simplesmente adicionar o comando rvm load no script, mas meu script dependeria do ambiente e isso não seria aceitável.

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

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

Graças a isso posso carregar o rvm no arquivo que defini 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 roteiro e deus funcionam conforme o esperado.

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

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

Obrigado novamente!

Responder1

Quando você faz:

su some_user -c 'some_command'    

O some_commandserá executado como:

bash -c 'some_command'

Supondo bashque some_usero shell esteja definido em /etc/passwd.

Agora, quando você faz isso, bash -c 'some_command'você está basicamente gerando umnão interativo(e clarosem login) sessão de bash. Como nenhum arquivo é originado pelo shell enquanto estiver no modo não interativo, nenhum arquivo está sendo lido de maneira esperada.

Observe que ~/.profileé originado em uma sessão interativa de login bashe ~/.bashrcé originado em uma sessão interativa sem login de bash. Observe também que as fontes do Ubuntu ~/.bashrcsão do ~/.profile.

Verifique a INVOCATIONseção de man bashpara ter mais ideia.

informação relacionada