Bash scripting: 365-024 = 345?

3

Eu estou tentando construir alguns scripts para iniciantes com o bash. Quero saber quantos dias restam hoje até o final do ano, usando o programa de datas.

Então, estou usando uma variável current_date = $ (date +% j) para obter o número do dia que temos agora.

Se eu echo $ current_date estou obtendo um resultado de 024 , como normalmente esperado, porque temos 24 de janeiro.

Então 365-024 são os dias restantes. E aí vem minha consulta. Fazendo o cálculo, digamos calc 365-024 estou obtendo o valor de 345, em vez de 341 .

O que há de errado? Tem algo a ver com o zero na frente ( 0 24), não é?

    
por Skemelio 24.01.2016 / 15:57

2 respostas

2

O que há de errado? Tem algo a ver com o zero na frente (024), não é?

Sim, é verdade. O percentual principal0 significa que o número é interpretado como um número Octal (base 8).

  • Octal 024 == Decimal 20.

Para interpretar o número como um número decimal, use:

$ echo $((024))
20

Para obter mais informações, consulte como suprimir a interpretação do número bash octal? (para ser interpretado como decimal) que aborda especificamente esse problema ao realizar cálculos com date .

Constantes Numéricas

A shell script interprets a number as decimal (base 10), unless that number has a special prefix or notation.

  • A number preceded by a 0 is octal (base 8).
  • A number preceded by 0x is hexadecimal (base 16).
  • A number with an embedded # evaluates as BASE#NUMBER (with range and notational restrictions).

Representation of numerical constants

#!/bin/bash
# numbers.sh: Representation of numbers in different bases.

# Decimal: the default
let "dec = 32"
echo "decimal number = $dec"             # 32
# Nothing out of the ordinary here.


# Octal: numbers preceded by '0' (zero)
let "oct = 032"
echo "octal number = $oct"               # 26
# Expresses result in decimal.
# --------- ------ -- -------


# Hexadecimal: numbers preceded by '0x' or '0X'
let "hex = 0x32"
echo "hexadecimal number = $hex"         # 50

echo $((0x9abc))                         # 39612
#     ^^      ^^   double-parentheses arithmetic expansion/evaluation
# Expresses result in decimal.



# Other bases: BASE#NUMBER
# BASE between 2 and 64.
# NUMBER must use symbols within the BASE range, see below.


let "bin = 2#111100111001101"
echo "binary number = $bin"              # 31181

let "b32 = 32#77"
echo "base-32 number = $b32"             # 231

let "b64 = 64#@_"
echo "base-64 number = $b64"             # 4031
# This notation only works for a limited range (2 - 64) of ASCII characters.
# 10 digits + 26 lowercase characters + 26 uppercase characters + @ + _


echo

echo $((36#zz)) $((2#10101010)) $((16#AF16)) $((53#1aA))
                                         # 1295 170 44822 3375


#  Important note:
#  --------------
#  Using a digit out of range of the specified base notation
#+ gives an error message.

let "bad_oct = 081"
# (Partial) error message output:
#  bad_oct = 081: value too great for base (error token is "081")
#              Octal numbers use only digits in the range 0 - 7.

exit $?   # Exit value = 1 (error)

# Thanks, Rich Bartell and Stephane Chazelas, for clarification.

Fonte Guia avançado de script de script - Constantes numéricas

    
por 24.01.2016 / 16:07
1

Escrever números com 0 à esquerda é uma convenção para a notação octal, assim como o prefixo 0x é para hexadecimal. Então 024 é interpretado como 2 * 8 + 4 == 20. Veja a saída do comando:

echo $(( 024 ))

Retire zeros à esquerda usando exemplos de código do código @ steeldriver no comentário abaixo.

    
por 24.01.2016 / 16:01