[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: Eigenatiges BASH problem...



Bruno Hertz wrote on 24/03/2005 00:01:

[stripped]

Also irgendwie ist das Verhalten der Bash bei mir schon sehr merkwürdig.

Voraussetzung: Verzeichnis mit leeren Dateien der Namen
a b c d e f g A B C D E F G

weiterhin: Skript (../t.sh vom fraglichen Verzeichnis aus) mit folgendem Inhalt:

======================================================
#!/bin/bash
unset LC_CTYPE LC_ALL LC_COLLATE
export LC_CTYPE=$1
printenv | grep LC
for i in `echo [A-C]`; do
	echo $i
done
======================================================

Dann noch in der aktuellen interaktiven Shell LC_COLLATE=de_DE gesetzt. So, jetzt rufe ich das Skript auf:

# ../t.sh C
LC_COLLATE=C
A
b
B
c
C

Hä? Laut Deiner Aussage müsste das eigentlich nur A B und C (nach LC_COLLATE=C) ausgeben. Wenn ich statt C de_DE oder us_US angebe, dann bleibt die Ausgabe wie oben gezeigt.

Setze ich jetzt in meiner interaktiven Shell LC_COLLATE auf C (oder lösche es samt der anderen LC_* Variablen), dann bleibt die Ausgabe des Scripts wieder völlig unbeeindruckt vom Übergabeparameter, abgesehen von der Ausgabe der LC_COLLATE-Zeile. Nur sieht es diesmal so aus:

# ../t.sh de_DE
LC_COLLATE=de_DE
A
B
C

Hä? Laut Deiner Aussage müsste das Script eigentlich A b B c C ausgeben, oder?

Um es richtig schön zu machen, hier noch zwei Beispiele:

# LC_COLLATE=C ../t.sh de_DE
LC_COLLATE=de_DE
A
B
C

# LC_COLLATE=de_DE ../t.sh C
LC_COLLATE=C
A
b
B
c
C

Jetzt schlauer? Hint: Selbst die angeblichen Subshells sind nicht wirklich eigene Instanzen der Bash sondern werden intern aufgelöst. Da die Shell die Pattern Expansion macht, ist also fraglich, was bei ihrem Aufruf der Wert von LC_COLLATE war.

Und so habe ich das obige Script dazu gebracht, das zu tun, was ich wollte:

======================================================
#!/bin/bash

LOOPED=0
if [ "$1" = "-loop" ]; then
	LOOPED=1
	shift
fi

unset LC_CTYPE LC_ALL LC_COLLATE
export LC_COLLATE=$1

if [ "$LOOPED" = 0 ]; then
	printenv | grep LC
	$0 -loop "$@"
else	
	echo looped:
	printenv | grep LC
	for i in [A-C]; do
		echo $i
	done
fi
======================================================

Alles klar?

Ciao,
Sven



Reply to: