Estou executando uma nova instalação Oneiric (ou seja, não uma atualização) em dois sistemas diferentes e executando o mesmo conjunto de problemas aparentemente relacionados.
O mais frustrante é que, quando eu uso o .profile e o .bashrc que carrego comigo do Mac OS X, o login no X via LightDM me desconecta imediatamente. Acredito que isso seja causado pelo fato de que, ao executar "/ bin / sh", ele se comporta como / bin / dash, mas ainda tem a variável $ SHELL definida como / bin / bash.
Extrapolação
Eu tenho um enorme .bashrc
. Você pode vê-lo aqui, se quiser, mas seu conteúdo provavelmente não é relevante, além do fato de estar cheio de basismos e de funcionar sem erros no xterm ou no console virtual.
Minha .profile
aparência é esta (abreviada):
case $SHELL in
*bash*)
if [ -f $HOME/.bashrc -a -r $HOME/.bashrc ]; then
. $HOME/.bashrc
fi
;;
esac
Se eu tentar efetuar login no X via LightDM, ele efetuará o logoff imediatamente. Eu recebo erros .xsession-errors
relacionados ao meu .bashrc que se parecem com este (abreviado):
/home/mrled/.bashrc: 103: [[: not found
[: 103: Linux: unexpected operator
[: 274: -P :: unexpected operator
/home/mrled/.bashrc: 520: complete: not found
Como eu disse, quando executo o bash em um console virtual, não recebo esses erros. Além disso, se eu remover meu .profile, posso fazer login no X muito bem. (Também posso fazer login em um console virtual e usá-lo startx
para iniciar uma sessão X que funcione, mas essa não é uma solução de longo prazo).
No entanto, eu descobri que se eu correr /bin/sh -l
, eu não obter os erros. Aqui está uma sessão de exemplo (nota: o prompt do bash para o qual simplifiquei bash>
e o prompt sh é apenas $
):
bash> echo $SHELL
/bin/bash
bash> echo $BASH_VERSION
4.2.10(1)-release
bash> /bin/sh -l
/home/mrled/.bashrc: 103: [[: not found
[: 103: Linux: unexpected operator
[: 274: -P :: unexpected operator
/home/mrled/.bashrc: 520: complete: not found
$ echo $SHELL
/bin/bash
$ echo $BASH_VERSION
$
Q1: Por que isso está acontecendo?
Eu entendo que / bin / sh agora aponta para o dash em vez do bash , mas se isso é verdade, por que $SHELL
ainda está retornando /bin/bash
?
P2: O que posso fazer para solucionar isso?
Existe uma maneira de contornar isso? Quero manter meu perfil carregando .bashrc para obter o mesmo ambiente nos shells de logon e não-logon, mas obviamente só quero que ele seja carregado para o bash, não / bin / sh mascarado como bash.
Você deve ter notado a diferença no conteúdo das variáveis $ BASH_VERSION acima. Eu tentei agrupar meu .profile em algo como isto:
if [ -n $BASH_VERSION ]; then
# the rest of my .profile as above
fi
O -n
teste deve retornar true somente se o comprimento da string for diferente de zero, no entanto, embora na sessão acima, quando estou executando, /bin/sh -l
ele retorne uma string vazia para $ BASH_VERSION, quando incluída no meu .profile como este , passa no teste! Eles procedem da fonte do meu .bashrc e me dão os mesmos erros de antes.
Agora estou realmente confuso.
fonte
dash -l
também mostra$SHELL
ter o valor/bin/bash
.$SHELL
é o que o último campo em/etc/passwd
(ougetent passwd
) diz.~/.profile
bash, itens específicos do bash~/.bashrc
e ter a~/.bash_profile
origem dos dois.Respostas:
Você pode fazer o fato de que
$BASH_VERSION
está em branco nodash
trabalho para você:fonte
if [ "$BASH_VERSION" = '' ]
-n
, ou nada . (. 1, embora= ''
funciona perfeitamente bem.)Você só precisa usar aspas na variável
BASH_VERSION
para usar-n
fonte
[ "$EMPTY_STRING" ]
avalia false, você nem precisa do-n
. Você só precisa citar a variávelUse
/proc/[PID]/cmdline
para ver com o que o script está sendo executado e teste o que ele contém. A$$
variável nos fornecerá o PID do shell em execução. Assim, podemos criar um script como este,Aqui está um teste do mesmo script:
fonte
bash
em seu nome; não é incomum que obash
executável seja executado através de um link simbólico com outro nome. Normalmente, alguém ainda gostaria de considerar esse Bash. Além disso, o padrão é correspondido em qualquer lugar/proc/$$/cmdline
, o que deve ser possível de corrigir, mas lembre-se de que os argumentoscmdline
são delimitados por caracteres nulos.grep -qE '(^|/)bash$'
parece que deve funcionar, mas dá um falso positivo quando qualquer argumento ébash
.