Por que o bash pensa: 016 + 1 = 15?

60

Alguém pode me explicar por que um número com 0 à esquerda dá esse comportamento engraçado?

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

Irá imprimir:

016 + 1 = 15

DeltaLima
fonte
3
Psst: printf "%03d\n" 10é completamente utilizável no bash para obter um zero inicial para nomes de arquivos e outros.
Squeezy
@ Squeezy Obrigado, mas essa parte já estava funcionando. O problema real não era obter um nome de arquivo com um 0. inicial. Ele estava descobrindo qual era o número de arquivo com o número mais alto e, em seguida, criando a próxima sequência, usando printf "prefix-% 03d.tif" $ SUM.
DeltaLima 08/01
8
Observe que você mesmo poderia ter descoberto isso fazendo #echo $((016))
Mehrdad
2
Para sua informação, isso é verdade em muitas linguagens de programação: C, C ++, Javascript.
Paul Draper

Respostas:

128

O mal-entendido é que os números não significam o que você espera.

Um zero à esquerda indica um número com a base 8. Ou seja, 016é o mesmo que 8#16. Se você deseja manter o zero à esquerda, precisa 10#016.

> num=016
> echo $((num))
14
> echo $((10#$num))
16
Hauke ​​Laging
fonte
23
Existem 10 tipos de pessoas no mundo. Quem entende binário, quem não entende, quem não esperava uma piada de base 8 e 5 outros tipos de pessoas.
Jon História
42

Porque:

~$ echo $((NUM))
14

se o número começa com 0, é considerado um valor octal e 16 em octal é 14 em decimal.

fredtantini
fonte
2
Isso faz sentido e explica por que meu script estava substituindo meus arquivos antigos :-(
DeltaLima 8/15/15