Como meu script pode determinar se está sendo executado por bash ou dash?

12

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 uso o .profile e o .bashrc que carrego comigo do Mac OS X, fazer o login no X via LightDM me faz logout 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 ver aqui se quiser, mas seu conteúdo provavelmente não é relevante, além do fato de que ele é cheio de bashisms, e o fato de que ele funciona sem erros dentro do xterm ou em um console virtual.

Meu .profile é assim (abreviado):

case $SHELL in 
*bash*)
    if [ -f $HOME/.bashrc -a -r $HOME/.bashrc ]; then
        . $HOME/.bashrc
    fi
    ;;
esac

Se eu tentar entrar no X via LightDM, ele me registrará imediatamente. Eu recebo erros em .xsession-errors relacionados ao meu .bashrc que se parecem com isso (abreviados):

/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 eu executo o bash de um console virtual, não recebo esses erros. Além disso, se eu remover meu .profile, posso fazer o login em X bem. (Eu também posso fazer login em um console virtual e usar startx para iniciar uma sessão X que funcione, mas isso obviamente não é uma solução de longo prazo.)

No entanto, descobri que, se eu executar /bin/sh -l , faço os erros. Aqui está um exemplo de sessão (nota: o prompt do bash eu simplifiquei para 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 traço em vez de bash , mas se isso for verdade, então por que $SHELL ainda está retornando /bin/bash ?

Q2: O que posso fazer para contornar isso?

Existe uma maneira de contornar isso? Eu quero manter o meu perfil carregando o .bashrc para que eu obtenha o mesmo ambiente em ambos os shells de login e não-login, mas obviamente eu só quero que ele carregue para o bash, não / bin / sh masquerading como bash.

Você deve ter notado a diferença no conteúdo das variáveis $ BASH_VERSION acima. Eu tentei envolver meu .profile em algo assim:

if [ -n $BASH_VERSION ]; then
    # the rest of my .profile as above
fi

O -n test deve retornar true somente se o tamanho da string for diferente de zero, no entanto, mesmo que na sessão acima, quando eu estiver rodando em /bin/sh -l , ele retornará uma string vazia para $ BASH_VERSION, quando está incluído no meu .profile como este, passa no teste! Eles procedem a fonte meu .bashrc e me dão os mesmos erros como antes.

Agora estou realmente confuso.

    
por Micah R Ledbetter 22.01.2012 / 07:08

3 respostas

11

Você pode tornar o fato de que $BASH_VERSION está em branco em dash work for you:

if [ "$BASH_VERSION" = '' ]; then
    echo "This is dash."
else
    echo "This is bash."
fi
    
por Scott Severance 22.01.2012 / 10:47
5

Você só precisa usar aspas na variável BASH_VERSION para usar -n

if [ -n "$BASH_VERSION" ];then
 echo "this is bash"; 
else 
 echo "this is dash";
fi
    
por GM-Script-Writer-62850 13.05.2013 / 16:29
1

Use /proc/[PID]/cmdline para ver com o que o script está sendo executado e teste o que ele contém. A variável $$ nos dará o PID do shell em execução. Assim, podemos fazer um script como este,

#!/bin/bash
if grep -q 'bash' /proc/$$/cmdline ;
then
    echo "This is bash"
else
    echo "This is some other shell"
fi

Aqui está um teste do mesmo script:

$> bash test_script.sh                                                                                                
This is bash
$> dash test_script.sh                                                                                                
This is some other shell
    
por Sergiy Kolodyazhnyy 06.04.2016 / 16:45