Ich führe eine neue Oneiric-Installation (dh kein Upgrade) auf zwei verschiedenen Systemen aus und stoße auf die gleichen scheinbar verwandten Probleme.
Am frustrierendsten ist, dass mich die Anmeldung bei X über LightDM sofort abmeldet, wenn ich die Dateien .profile und .bashrc verwende, die ich von Mac OS X mitgenommen habe. Ich glaube, das liegt an der Tatsache, dass es sich beim Ausführen von "/ bin / sh" wie / bin / dash verhält, aber die Variable $ SHELL immer noch auf / bin / bash gesetzt ist.
Hochrechnung
Ich habe eine riesige .bashrc
. Sie können es hier sehen, wenn Sie möchten, aber der Inhalt ist wahrscheinlich nicht relevant, abgesehen von der Tatsache, dass es voller Bashismen ist und dass es in xterm oder auf einer virtuellen Konsole fehlerfrei 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, werde ich sofort wieder abgemeldet. Ich bekomme Fehler in .xsession-errors
Bezug auf meine .bashrc, die so 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, werden diese Fehler nicht angezeigt. Wenn ich mein .profile entferne, kann ich mich außerdem problemlos bei X anmelden. (Ich kann mich auch bei einer virtuellen Konsole anmelden und startx
damit eine funktionierende X-Sitzung einleiten, aber dies ist natürlich keine langfristige Lösung.)
Allerdings habe ich festgestellt , dass , wenn ich laufe /bin/sh -l
, ich kann die Fehler bekommen. Hier ist eine Beispielsitzung (Hinweis: Die Bash-Eingabeaufforderung, auf die ich vereinfacht habe bash>
, und die Sh-Eingabeaufforderung sind 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
$
F1: Warum passiert das?
Ich verstehe, dass / bin / sh jetzt eher auf dash als auf bash verweist , aber wenn das wahr ist, warum $SHELL
kehrt es dann immer noch zurück /bin/bash
?
F2: Was kann ich tun, um das Problem zu umgehen?
Gibt es eine Möglichkeit, dies zu umgehen? Ich möchte, dass mein Profil .bashrc lädt, damit ich auf Anmelde- und Nicht-Anmelde-Shells die gleiche Umgebung erhalte, aber natürlich soll es nur für die Bash selbst geladen werden, nicht für / bin / sh, das sich als Bash tarnt.
Möglicherweise haben Sie den Unterschied im Inhalt der obigen Variablen $ BASH_VERSION bemerkt. Ich habe versucht, mein .profile in etwas einzuwickeln:
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 der Zeichenfolge nicht null ist, obwohl in der obigen Sitzung, wenn ich unter /bin/sh -l
dieser ausgeführt werde, eine leere Zeichenfolge für $ BASH_VERSION zurückgegeben wird, wenn diese in meinem Profil wie folgt enthalten ist , es besteht den Test! Wenn sie fortfahren, meine .bashrc-Datei zu beziehen, geben Sie mir dieselben Fehler wie zuvor.
Jetzt bin ich wirklich verwirrt.
quelle
dash -l
auch$SHELL
der Wert angezeigt wird/bin/bash
.$SHELL
ist, was das letzte Feld in/etc/passwd
(odergetent passwd
) sagt.~/.profile
und bash-spezifische Dinge einbinden~/.bashrc
und beide~/.bash_profile
Quellen haben .Antworten:
Sie können die Tatsache, dass
$BASH_VERSION
in derdash
Arbeit für Sie leer ist :quelle
if [ "$BASH_VERSION" = '' ]
-n
oder nichts . (+1,= ''
funktioniert aber sehr gut.)Sie müssen lediglich Anführungszeichen für die
BASH_VERSION
zu verwendende Variable verwenden-n
quelle
[ "$EMPTY_STRING" ]
false ausgewertet wird, brauchst du das nicht mal-n
. Sie müssen nur die Variable in Anführungszeichen setzen.Verwenden Sie
/proc/[PID]/cmdline
diese Option, um zu sehen, womit das Skript ausgeführt wird, und um zu testen, was es enthält. Die$$
Variable gibt uns die PID der laufenden Shell. So können wir ein Skript wie dieses machen,Hier ist ein Test desselben Skripts:
quelle
bash
in seinem Namen haben; Es ist nicht ungewöhnlich, dass diebash
ausführbare Datei über einen Symlink mit einem anderen Namen ausgeführt wird. Normalerweise würde man diesen Bash immer noch in Betracht ziehen wollen. Außerdem wird das Muster an einer beliebigen Stelle in abgeglichen/proc/$$/cmdline
, was korrigiert werden sollte. Beachten Sie jedoch, dass Argumente in durchcmdline
Nullzeichen getrennt sind.grep -qE '(^|/)bash$'
fühlt sich an wie es funktionieren sollte, gibt aber ein falsches positives wenn irgendein Argument istbash
.