No meu caso .profile
, uso o código a seguir para garantir que aliases e funções relacionados ao Bash sejam originados apenas se o shell de logon for realmente o Bash :
# If the current (login) shell is Bash, then
if [ "${BASH_VERSION:-}" ]; then
# source ~/.bashrc if it exists.
if [ -f "$HOME/.bashrc" ]; then
. "$HOME/.bashrc"
fi
fi
Atualmente, estou colocando meus arquivos de configuração de shell, scripts e funções sob controle de versão. Recentemente, também iniciei o processo de remoção de Bashisms casuais de scripts de shell que não se beneficiam de recursos específicos do Bash, por exemplo, substituindo function funcname()
por funcname()
.
Para o meu repositório de arquivos shell, configurei um gancho de pré-confirmação que executa o checkbashisms
utilitário do pacote devscripts do Debian em cada sh
arquivo do repositório para garantir que eu não introduza inadvertidamente sintaxe específica do Bash. No entanto, isso gera um erro para o meu .profile
:
possible bashism in .profile line 51 ($BASH_SOMETHING):
if [ "${BASH_VERSION:-}" ]; then
Fiquei me perguntando se havia uma maneira de verificar qual shell está sendo executado que não acionaria um aviso checkbashisms
.
Verifiquei a lista de variáveis relacionadas ao shell listadas pelo POSIX na esperança de que uma delas pudesse ser usada para mostrar o shell atual. Também examinei as variáveis definidas em um shell Dash interativo, mas, novamente, não consegui encontrar um candidato adequado.
No momento, excluí o .profile
processamento por checkbashisms
; Como é um arquivo pequeno, não é difícil verificá-lo manualmente. No entanto, depois de pesquisar o problema, eu ainda gostaria de saber se existe um método compatível com POSIX para determinar qual shell está sendo executado (ou pelo menos uma maneira que não causa checkbashisms
falha).
Antecedentes / esclarecimentos
Uma das razões pelas quais estou colocando meus arquivos de configuração do shell sob controle de versão é configurar meu ambiente em todos os sistemas nos quais atualmente efetuo logon regularmente: Cygwin, Ubuntu e CentOS (ambos 5 e 7, usando o Active Directory para usuários). autenticação). Costumo fazer logon através de ambientes X Windows / desktop e SSH para hosts remotos. No entanto, eu gostaria que isso fosse à prova do futuro e tivesse a menor dependência possível das dependências do sistema e de outras ferramentas.
Eu tenho usado checkbashisms
como uma verificação de integridade simples e automatizada para a sintaxe dos meus arquivos relacionados ao shell. Não é uma ferramenta perfeita, por exemplo, eu já apliquei um patch para que não reclame sobre o uso dos command -v
meus scripts. Enquanto pesquisava, aprendi que o objetivo real do programa é garantir a conformidade com a política Debian que, como eu a entendo, é baseada no POSIX 2004 em vez de 2008 (ou na revisão de 2013).
fonte
.bash_profile
que use ambas.profile
e (condicionalmente).bashrc
.Respostas:
Seu
O código é totalmente compatível com POSIX e a melhor maneira de verificar se você está executando no momento
bash
. Claro que a$BASH_VERSION
variável é específica do bash, mas é por isso que você a está usando! Para verificar se você está correndobash
!Observe que
$BASH_VERSION
será definido sebash
é chamado comobash
oush
. Depois de afirmar que está sendo executadobash
, você pode usar[ -o posix ]
como um indicador que o shell foi chamado comosh
(embora essa opção também seja definida quando POSIXLY_CORRECT estiver no ambiente oubash
for chamado com-o posix
, ou com SHELLOPTS = posix no ambiente. Mas em todos esses casos,bash
se comportará como se fosse chamado comosh
).Outra variável que você pode usar em vez de
$BASH_VERSION
e quecheckbashism
não parece reclamar, a menos que seja aprovada a-x
opção$BASH
. Isso também é específico parabash
um que você também deve poder usar para determinar se está executandobash
ou não.Eu também argumentaria que não é realmente um uso adequado
checkbashisms
.checkbashisms
é uma ferramenta para ajudá-lo a escreversh
scripts portáteis (de acordo com ash
especificação da política Debian, um superconjunto do POSIX), ajuda a identificar a sintaxe não padrão introduzida por pessoas que escrevem scripts em sistemas nos quaissh
há um link simbólicobash
.A
.profile
é interpretado por diferentes shells, muitos dos quais não são compatíveis com POSIX. Geralmente, você não usash
como seu shell de login, mas shellzsh
,fish
oubash
com recursos interativos mais avançados.bash
ezsh
, quando não for chamado comosh
e quando seu respectivo arquivo de sessão de perfil (.bash_profile
,.zprofile
) não for compatível com POSIX (especialmentezsh
), mas ainda for lido.profile
.Portanto, não é a sintaxe do POSIX desejada,
.profile
mas uma sintaxe compatível com o POSIX (forsh
),bash
ezsh
se você usar esses shells (possivelmente até o Bourne como o shell Bourne também lê,.profile
mas não é comumente encontrado em sistemas baseados em Linux) )checkbashisms
definitivamente o ajudaria a descobrir os basismos, mas pode não apontar a sintaxe do POSIX que não é compatível comzsh
oubash
.Aqui, se você deseja usar um
bash
código específico (como a solução alternativa dessebash
bug, que não lê~/.bashrc
em shells de logon interativo), uma abordagem melhor seria~/.bash_profile
fazer isso (antes ou depois da busca~/.profile
onde você colocou sua sessão comum inicializações).fonte
checkbashisms
por causa da variável usada.$0
para este caso em particular?sh
e algum outro shell chamado comosh
.dash
outro shell não bash foi chamado incorretamente comargv[0] == "bash"
, o que é totalmente legal, se improvável.Geralmente se usa
$0
para esse fim. No site que você vinculou, está:fonte
$0
o nome de um script de shell que esqueci que ele também pode se referir ao shell atual. Obrigado!exec
família porque elas permitem que o programa de chamada identifique o binário a ser executado separadamente da cadeia a ser passada como argumento 0Normalmente, a variável de ambiente SHELL informa o shell padrão. Você não precisa originar manualmente o arquivo .bashrc (não é verdade, veja a atualização abaixo), o bash deve fazer isso automaticamente, apenas verifique se ele está no diretório $ HOME.
A outra opção é fazer algo como:
que informará o comando (sem argumentos, o = sem valor não exibirá os cabeçalhos das colunas) do processo atual. Exemplo de saída:
ATUALIZAR:
Eu estou corrigido! :)
O .bashrc nem sempre é originado como mencionado nos comentários abaixo e /programming/415403/whats-the-difference-between-bashrc-bash-profile-and-environment
Assim, você pode mover seu .bashrc para .bash_profile e ver se isso funciona sem ter que fazer o teste. Caso contrário, você tem o teste acima.
fonte
.bashrc
não é realmente originário de um shell de login, mas.profile
(se existir) ou.bash_profile
é.SHELL
não é especificado pelo POSIX e, infelizmente, também não é acmd
opção de formatops
.ps -o cmd= $$
deva funcionar praticamente em todos os lugares, a$SHELL
variável é completamente irrelevante. Esse é o shell padrão do usuário e não tem influência sobre qual shell está sendo executado no momento ou qual shell está executando um script de shell.~/.profile
quando iniciados como shells de login. Então, por exemplo, você$SHELL
poderia sercsh
e você correbash -l
. Isso iniciará o bash como um shell de logon, e será lido~/.profile
, mas você$SHELL
ainda apontará paracsh
. Além disso,.profile
pode ser fornecido explicitamente por outro script. Como o OP está buscando a máxima robustez, todos os tipos de casos devem ser considerados. De qualquer forma,$SHELL
não fornece nenhuma informação útil sobre o shell em execução no momento.SHELL
não ser especificado por POSIX: pubs.opengroup.org/onlinepubs/9699919799/basedefs/...A pergunta pede o shell de login do usuário, bem como o shell atual , de uma maneira que agrade
checkbashisms
. Se esse for o shell no qual o usuário efetuou login, eu usaria o de/etc/passwd
, por exemplo,Os usuários podem, é claro, iniciar um novo shell após efetuar o login. É claro que, se um é bash e o outro não, os testes das variáveis de ambiente do bash podem não ajudar.
Alguns podem querer usar,
getent
e não apenas opasswd
arquivo (mas isso não estaria no escopo da pergunta).Com base no comentário sobre LDAP e na sugestão de
logname
, este formulário alternativo pode ser usado:Ao testá-lo, notei que
logname
não gosta de sua entrada redirecionada (então deixei a expressão dividida). Uma verificação rápida mostra quegetent
deve funcionar nas plataformas mencionadas (embora isso deva ter sido fornecido na pergunta original):fonte
$(logname)
).id
ou uma variável modificável pelo usuário é uma escolha diferente.$(logname)
, não$LOGNAME
. O ID do usuário e o shell de login são derivados do nome de usuário usado no login. Você não pode voltar do ID do usuário para o shell de login, exceto nos sistemas em que há apenas um nome de usuário por ID de usuário. Ou IOW, a chave primária no banco de dados do usuário é o nome de usuário, não o uid.