Perché bash pensa: 016 + 1 = 15?


60

Qualcuno può spiegarmi perché un numero con uno 0 iniziale dà questo comportamento divertente?

#!/bin/bash
NUM=016 
SUM=$((NUM + 1)) 
echo "$NUM + 1 = $SUM"

Stampa:

016 + 1 = 15


3
Psst: printf "%03d\n" 10è completamente utilizzabile in bash per ottenere uno zero iniziale per nomi di file e simili.
Squeezy,

@Squeezy Grazie, ma quella parte stava già funzionando. Il vero problema non era ottenere un nome file con uno 0 iniziale: era scoprire quale fosse il nome file con il numero più alto e quindi creare il prossimo in sequenza, usando printf "prefix-% 03d.tif" $ SUM.
DeltaLima,

8
Nota che avresti potuto capirlo da solo facendoecho $((016))
Mehrdad il

2
Cordiali saluti, questo è vero in molti linguaggi di programmazione: C, C ++, Javascript.
Paul Draper,

Risposte:


128

L'incomprensione è che i numeri non significano ciò che ti aspetti.

Uno zero iniziale indica un numero con base 8. Ie 016è lo stesso di 8#16. Se si desidera mantenere lo zero iniziale, è necessario 10#016.

> num=016
> echo $((num))
14
> echo $((10#$num))
16

23
Ci sono 10 tipi di persone nel mondo. Quelli che capiscono il binario, quelli che non lo fanno, quelli che non si aspettavano uno scherzo di base 8 e altri 5 tipi di persone.
Jon Story,

42

Perché:

~$ echo $((NUM))
14

se il numero inizia con 0, viene considerato un valore ottale e 16 in ottale è 14 in decimale.


2
Ciò ha perfettamente senso e spiega perché la mia sceneggiatura stava sovrascrivendo i miei vecchi file :-(
DeltaLima
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.