2015-03-21 18 views
12

Per quanto ne sapevo, ci si può aspettare che [[ e [ si comportino in gran parte lo stesso, tenendo conto di alcune funzioni extra [[. Ma di recente ho notato una discrepanza nel modo in cui tratta bash espansioni ottale:differenza di espansione ottale tra [e [[?

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

ma

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

Perché quest'ultima espressione cadere la conversione automatica ottale? Le espressioni come -eq sono "aritmetiche" in base allo help test in Bash e allo e inoltre, in base alla prossima sezione delle costanti del manuale di riferimento con uno zero iniziale, può essere trattato come ottale.

POSIX sh è un po 'meno chiara on the subject: Anche se POSIX espressioni aritmetiche ancora espandono interi leader zero al loro valore ottale, si riferisce a -eq espressioni test come algebrica, non aritmetica.

Esiste qualche documentazione o prova che suggerisce che bash fa una distinzione tra [[ e [ per l'espansione ottale di proposito, o è solo una funzione accidentale?

+0

+1; ma noto che sebbene '-eq' sia descritto come un" operatore aritmetico binario ", i suoi argomenti non * sono * descritti come" espressioni aritmetiche ". Quindi, ad esempio, '[b -eq 10]' non espande il parametro shell '$ b'. Quindi, anche se certamente avrebbe più senso che l'operatore consideri '010' come significato 8 anziché 10, non vedo nulla nel manuale che contraddica davvero il comportamento che stai vedendo. – ruakh

+2

'[[b -eq 8]]' sembra essere equivalente a '((b == 8))' (puoi omettere il '$'). La documentazione non sembra dirlo. – choroba

+0

@choroba buon punto, non mi ero nemmeno reso conto che '[[x -eq y]]' espande xey proprio come le espressioni '(())'. – kojiro

risposta

2

[[è noto come il comando di test esteso e si comporta come ksh88, è possibile trovare un'elaborazione qui: http://tldp.org/LDP/abs/html/testconstructs.html#DBLBRACKETS

Anche se avete bisogno di essere sicuri della base in bash è possibile utilizzare l'operatore # di base così:

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

Grazie, io lo faccio +1 perché il collegamento TLDP menziona effettivamente la discrepanza nella mia domanda direttamente. Detto questo, ksh93 apparentemente non fa ottale espansione in '$ (())', che fa partire anche da POSIX sh. (Non ho ksh88 a portata di mano, ma forse qualcuno con esso può commentare.) – kojiro

+0

Oh strano, ksh93 tratta i valori letterali con gli zeri iniziali come ottali, ma non fa lo stesso durante l'espansione. 'echo $ ((010)) -> 8', ma' x = 010; echo $ ((x)) -> 10'. Ho potuto vedere come questo comportamento potrebbe essere considerato conforme a POSIX. – kojiro

+0

Non in questo modo, ma se si 'x = 010; echo $ (($ x))' si dovrebbe ottenere 8. –