Wie kann mein Skript feststellen, ob es von bash oder von Dash ausgeführt wird?

12

Ich führe eine neue Oneiric-Installation (d. h. kein Upgrade) auf zwei verschiedenen Systemen durch und stoße in die gleichen scheinbar scheinbar zusammenhängenden Probleme.

Das frustrierendste daran ist, dass ich mich bei der Verwendung von .profile und .bashrc, die ich von Mac OS X mitgenommen habe, sofort bei Log über LightDM bei X abmelde. Ich glaube, dass dies durch die Tatsache verursacht wird, dass es sich bei der Ausführung von "/ bin / sh" wie / bin / dash verhält, aber die Variable $ SHELL immer noch auf / bin / bash gesetzt hat.

Extrapolation

Ich habe eine riesige .bashrc . Sie können es hier sehen, wenn Sie möchten, aber sein Inhalt ist wahrscheinlich nicht relevant, abgesehen von der Tatsache, dass es voller Bashismen ist, und die Tatsache, dass es innerhalb xterm oder auf einer virtuellen Konsole ohne Fehler funktioniert.

Mein .profile sieht so aus (abgekürzt):

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

Wenn ich versuche, mich über LightDM bei X anzumelden, meldet es mich sofort wieder zurück. Ich bekomme Fehler in .xsession-errors in Bezug auf meine .bashrc, die wie folgt aussehen (abgekürzt):

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

Wie gesagt, wenn ich bash von einer virtuellen Konsole aus starte, bekomme ich diese Fehler nicht. Außerdem, wenn ich meine .profile lösche, kann ich mich einfach in X einloggen. (Ich kann mich auch an einer virtuellen Konsole anmelden und startx verwenden, um eine X-Sitzung zu starten, die funktioniert, aber das ist natürlich keine langfristige Lösung.)

Ich habe jedoch festgestellt, dass ich die Fehler erhalte, wenn ich /bin/sh -l ausfühle. Hier ist eine Beispielsitzung (Anmerkung: die Bash-Eingabeaufforderung habe ich auf bash> vereinfacht, und die sh-Eingabeaufforderung ist nur $ ):

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: Warum passiert das?

Ich verstehe, dass / bin / sh jetzt eher auf strich als auf bash zeigt , aber wenn das stimmt, dann warum ist $SHELL gibt immer noch /bin/bash zurück?

F2: Was kann ich tun, um es zu umgehen?

Gibt es eine Möglichkeit, dies zu umgehen? Ich möchte, dass mein Profil loading .bashrc speichert, so dass ich die gleiche Umgebung sowohl für Login- als auch Nicht-Login-Shells bekomme, aber offensichtlich möchte ich nur, dass es für bash selbst geladen wird, nicht / bin / sh maskiert als bash.

Sie haben vielleicht den Unterschied im Inhalt der obigen $ BASH_VERSION Variablen bemerkt. Ich habe versucht, meine .profile in etwa wie folgt zu verpacken:

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

Der -n Test sollte nur dann true zurückgeben, wenn die Länge des Strings ungleich Null ist, obwohl ich in der obigen Sitzung, wenn ich unter /bin/sh -l laufe, eine leere Zeichenfolge für $ BASH_VERSION zurückgebe, Wenn es in meinem .profile wie folgt enthalten ist, besteht es den Test! Sie gehen weiter, um meine .bashrc zu finden und geben mir die gleichen Fehler wie zuvor.

Jetzt bin ich wirklich verwirrt.

    
Micah R Ledbetter 22.01.2012, 07:08
quelle

3 Antworten

11

Sie können die Tatsache, dass $BASH_VERSION leer ist, in dash für Sie arbeiten lassen:

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

Sie müssen nur Anführungszeichen für die Variable BASH_VERSION verwenden, um -n

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

Verwenden Sie /proc/[PID]/cmdline , um zu sehen, mit was das Skript ausgeführt wird, und testen Sie, was es enthält. Die Variable $$ gibt uns die PID der laufenden Shell. So können wir ein Skript wie dieses machen,

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

Hier ist ein Test des gleichen Skripts:

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

Tags und Links