De acordo com as Leis 12.965/2014 e 13.709/2018, que regulam o uso da Internet e o tratamento de dados pessoais no Brasil, ao me inscrever na newsletter do portal DICAS-L, autorizo o envio de notificações por e-mail ou outros meios e declaro estar ciente e concordar com seus Termos de Uso e Política de Privacidade.
Colaboração: Paulo Roberto Bagatini
Data de Publicação: 26 de maio de 2014
Ninguém está livre de ser pego desprevenido pela notação numérica do BASh:
$ echo $((010+070)) # 1 64 $ echo $(( 10+070)) # 2 66 $ echo $((010+ 70)) # 3 78 $ echo $((010+ 90)) # 4 98 $ echo $(( 10+090)) # 5 bash: 10+090: valor muito grande para esta base de numeração (token com erro é "090")
QUÊ BASE de numeração, tchê?
Octal, é claro. O BASh considera números que iniciam com zero como estando na base 8. Se estão na base 8, não podem ter dígitos maiores que 7 ;-)
Na dica Bashes Numéricas no BASh, foi mostrado que o BASh trabalha nativa e simultaneamente com bases numéricas diferentes:
Quando a operação ocorre interativamente e com números, no "estilo calculadora", basta não usar o zero cabide, e tudo estará resolvido:
$ echo $((10+70)) 80 $ echo $((10+90)) 100
Mas às vezes os números estão escondidos em variáveis. Às vezes a quantidade de dígitos foi padronizada com o comando printf, ou os valores foram gerados a partir da expansão de chaves (brace expansion) {000..010} ou com o comando seq. Outras vezes, simplesmente nos damos conta que uma variável que não era pra ter nada de anormal apareceu com um zero na frente do conteúdo, e agora temos que ficar implantando patches no nosso algoritmo para driblar essa idiossincrasia do nosso amigo BASh :-p
Em vez de apelar para o sed ou tr para tirar os zeros cabide salvando o resultado em uma variável auxiliar, podemos usar a notação explícita de bases numéricas do BASh e deixar bem claro para o shell que SIM, estamos trabalhando na base decimal! Pombas...
$ a=11 $ b=209 $ echo $((a+b)) # OK $ a=$(printf %04d 11) # 0011 $ b=$(printf %06d 209) # 000209 $ echo $((a+b)) bash: 000209: valor muito grande para esta base de numeração (token com erro é "000209") # Ops... $ echo $((10#$a+10#$b)) 220 # OK novamente
Observem a necessidade de deixar explícito também o que é variável e o que é dígito, quando usamos a notação explícita de base numérica:
$ echo $((10#a+10#b)) bash: 10#a: valor muito grande para esta base de numeração (token com erro é "10#a")
This policy contains information about your privacy. By posting, you are declaring that you understand this policy:
This policy is subject to change at any time and without notice.
These terms and conditions contain rules about posting comments. By submitting a comment, you are declaring that you agree with these rules:
Failure to comply with these rules may result in being banned from submitting further comments.
These terms and conditions are subject to change at any time and without notice.
Comentários (1)
Dica muito boa essa Bagatini, muito obrigado, acabei de aplicar hoje em um script que precisava comparar o dia atual que vinha com 0 na frente.