3

Я пытаюсь создать несколько сценариев для начинающих с помощью Bash. Я хочу узнать, сколько дней осталось с сегодняшнего дня до конца года, используя программу даты.

Поэтому я использую переменную current_date = $(date +% j), чтобы получить номер дня, который у нас сейчас.

Если я получу эхо $ current_date, я получу результат 024, как обычно и ожидается, потому что у нас 24 января.

Так что 365-024 осталось дней. И вот идет мой запрос. Делая вычисления, скажем, Calc 365-024 Я получаю значение 345 вместо 341.

В чем дело? Это как-то связано с нулем спереди (0 24), не так ли?

2 ответа2

2

В чем дело? Это как-то связано с нулем спереди (024), не так ли?

Да, это так. Ведущий 0 означает, что число интерпретируется как восьмеричное (основание 8) число.

  • Восьмеричное 024 == Десятичное число 20.

Чтобы интерпретировать число как десятичное число, используйте:

$ echo $((024))
20

Для получения дополнительной информации смотрите, как подавить интерпретацию восьмеричных чисел bash?(следует интерпретировать как десятичное число), которое конкретно решает эту проблему при выполнении расчетов с date .


Числовые Константы

Сценарий оболочки интерпретирует число как десятичное (основание 10), если только это число не имеет специального префикса или обозначения.

  • Число, которому предшествует 0, является восьмеричным (основание 8).
  • Число, которому предшествует 0x, является шестнадцатеричным (основание 16).
  • Число со встроенным # оценивается как BASE # NUMBER (с ограничениями по диапазону и обозначениям).

Представление числовых констант

#!/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.

Source Advanced Bash-Scripting Guide - Числовые константы

1

Запись чисел с начальным 0 является соглашением для восьмеричной нотации, так же, как префикс с 0x для шестнадцатеричного. Таким образом, 024 интерпретируется как 2 * 8+4 == 20. Смотрите вывод команды:

echo $(( 024 ))

Уберите начальные нули, используя примеры кода из кода @ steeldriver в комментарии ниже.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .