
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_command
será executado como:
bash -c 'some_command'
Supondo bash
que some_user
o 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 bash
e ~/.bashrc
é originado em uma sessão interativa sem login de bash
. Observe também que as fontes do Ubuntu ~/.bashrc
são do ~/.profile
.
Verifique a INVOCATION
seção de man bash
para ter mais ideia.