Come può il mio script determinare se viene eseguito da bash o dash?

12

Sto eseguendo una nuova installazione Oneiric (vale a dire non un aggiornamento) su due sistemi diversi e in esecuzione nello stesso insieme di problemi apparentemente correlati.

La parte più frustrante di questo gruppo è che, quando uso il .profile e .bashrc che ho portato con me da Mac OS X, l'accesso a X tramite LightDM mi disconnette immediatamente. Credo che questo sia causato dal fatto che, quando si esegue "/ bin / sh", si comporta come / bin / dash, ma ha ancora la variabile $ SHELL impostata su / bin / bash.

L'estrapolazione

Ho un'enorme .bashrc . Puoi vederlo qui se vuoi, ma probabilmente il suo contenuto non è rilevante, a parte il fatto che è pieno di bashismi e il fatto che funzioni senza errori all'interno di xterm o su una console virtuale.

Il mio .profile è simile a questo (abbreviato):

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

Se tento di accedere a X tramite LightDM, mi disconnetterà immediatamente. Ottengo errori in .xsession-errors relativi al mio .bashrc che assomiglia a questo (abbreviato):

/home/mrled/.bashrc: 103: [[: not found
[: 103: Linux: unexpected operator
[: 274: -P :: unexpected operator
/home/mrled/.bashrc: 520: complete: not found

Come ho detto, quando eseguo bash da una console virtuale, non ottengo questi errori. Inoltre, se rimuovo il mio .profile, posso accedere a X bene. (Posso anche accedere a una console virtuale e usare startx per avviare una sessione X che funziona, ma questa non è ovviamente una soluzione a lungo termine.)

Tuttavia, ho scoperto che se eseguo /bin/sh -l , I do ottengo gli errori. Ecco una sessione di esempio (nota: il prompt di bash che ho semplificato a bash> , e il prompt sh è solo $ ):

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: Perché sta succedendo questo?

Comprendo che / bin / sh ora punta al trattino piuttosto che bash , ma se è vero, allora perché è $SHELL restituisce ancora /bin/bash ?

Q2: cosa posso fare per aggirare il problema?

C'è un modo per aggirare questo problema? Voglio mantenere il mio profilo caricando .bashrc in modo da ottenere lo stesso ambiente su entrambe le shell di login e non di login, ma ovviamente lo voglio solo caricare per bash stesso, non / bin / sh masquerading come bash.

Potresti aver notato la differenza nei contenuti delle variabili $ BASH_VERSION qui sopra. Ho provato a completare il mio profilo .profile in qualcosa del genere:

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

Il test -n dovrebbe restituire true solo se la lunghezza della stringa è diversa da zero, tuttavia, anche se nella sessione precedente, quando sono in esecuzione in /bin/sh -l restituisce una stringa vuota per $ BASH_VERSION, quando è incluso nel mio .profile come questo, supera il test! Continuano a cercare il mio .bashrc e mi danno gli stessi errori di prima.

Ora sono veramente confuso.

    
posta Micah R Ledbetter 22.01.2012 - 07:08
fonte

3 risposte

11

Puoi fare in modo che $BASH_VERSION sia vuoto in dash lavori per te:

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

Devi solo usare le virgolette sulla variabile BASH_VERSION per usare -n

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

Utilizza /proc/[PID]/cmdline per vedere con cosa viene eseguito lo script e verificare ciò che contiene. La variabile $$ ci darà il PID della shell corrente. Quindi possiamo creare uno script come questo,

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

Ecco un test dello stesso script:

$> bash test_script.sh                                                                                                
This is bash
$> dash test_script.sh                                                                                                
This is some other shell
    
risposta data Sergiy Kolodyazhnyy 06.04.2016 - 16:45
fonte

Leggi altre domande sui tag