2015-03-21 13 views
12

Soweit ich das gewusst habe, [[ und [ kann erwartet werden, dass sie sich größtenteils gleich verhalten, unter Berücksichtigung einiger zusätzlicher Funktionen, die [[ haben. Aber vor kurzem bemerkte ich eine Diskrepanz in wie bash behandelt Oktal Erweiterungen:oktale Expansionsdifferenz zwischen [und [[?

$ b=010; echo $((b)) 
8 
$ [[ $b -eq 8 ]]; echo $? 
0 

aber

$ [ $b -eq 8 ]; echo $? 
1 
$ test $b -eq 8; echo $? 
1 
$ [ $b -eq 10 ]; echo $? 
0 

Warum dieser Ausdruck die automatische Oktal Umwandlung fallen? Ausdrücke wie -eq sind "Arithmetic" gemäß help test in Bash und der , und ferner können gemäß dem nächsten Abschnitt des Referenzhandbuchs Konstanten mit einer führenden Null als oktal behandelt werden.

POSIX sh ist etwas weniger klar on the subject: Obwohl POSIX arithmetische Ausdrücke noch führende Null verschiedenen ganzen Zahlen den Wert ihrer Oktal erweitern, um es zu -eq Ausdrücke in test als algebraische, nicht Arithmetik bezieht.

Gibt es Belege oder Beweise, die darauf hindeuten, dass Bash zw. [[ und [ absichtlich eine oktale Erweiterung vornimmt oder nur ein zufälliges Merkmal ist?

+0

+1; aber ich bemerke, dass, obwohl "-eq" als "arithmetischer binärer Operator" beschrieben wird, seine Argumente * nicht * als "arithmetische Ausdrücke" beschrieben werden. So erweitert zum Beispiel '[b -eq 10]' den Shell-Parameter '$ b' nicht. Es wäre also sicherlich sinnvoller, wenn dieser Operator "010" eher als 8 als 10 behandelt, aber ich sehe nichts in dem Handbuch, das wirklich dem Verhalten widerspricht, das Sie sehen. – ruakh

+2

'[[b -eq 8]]' scheint äquivalent zu '((b == 8))' (Sie können das '$' weglassen). Die Dokumentation scheint das nicht zu sagen. – choroba

+0

@choroba guter Punkt, ich hatte nicht einmal bemerkt, dass '[[x -eq y]]' x und y genauso ausdehnt wie '(()) Ausdrücke. – kojiro

Antwort

2

[[wird als erweiterte Testbefehl bekannt und verhält sich wie ksh88 Sie eine Ausarbeitung finden Sie hier: http://tldp.org/LDP/abs/html/testconstructs.html#DBLBRACKETS

Auch wenn Sie in der Bash sicher der Basis sein, müssen Sie die # Base Operator verwenden können so:

b=010; echo $((10#$b)) 
10 
b=10; echo $((8#$b) 
8 
b=013; echo $((8#$b)) 
11 
+0

Danke, ich werde das nur, weil TLDP-Link tatsächlich die Diskrepanz in meiner Frage direkt erwähnt.Das heißt, ksh93 tut anscheinend nicht oktal Erweiterung in '$ (())', was es sogar von POSIX sh ableiten lässt. (Ich habe ksh88 nicht zur Hand, aber vielleicht kann jemand damit kommentieren.) – kojiro

+0

Oh komisch, ksh93 behandelt Literale mit führenden Nullen als oktal, tut dies aber nicht bei der Expansion. echo $ ((010)) -> 8', aber 'x = 010; echo $ ((x)) -> 10'. Ich konnte sehen, wie dieses Verhalten als POSIX-konform angesehen werden kann. – kojiro

+0

Nicht so, aber wenn du 'x = 010; echo $ (($ x))' solltest du 8 bekommen. –