Как запустить infinite_number_loop
в bash? , как показано ниже:
для i в выражении infinite_number_statement
do date +% Y-% m-% d -d "$ i день назад" 2> & 1> / dev / null
если [$? -ne 0]
затем эхо $ i
фи
Выполнено
Если я запустил этот цикл в терминале на моем локальном компьютере, возникнут ли проблемы? (Я пробовал использовать большой диапазон случайных чисел с помощью для цикла
и однажды завис.)
Не бесконечный цикл, но лучший способ найти фактический предел даты:
#!/bin/bash
j=$((1<<61))
i=0
while ((j>0)); do
if date +'%Y-%m-%d' -d "$((i+j)) days ago" >/dev/null 2>&1; then
((i+=j)) ; # printf 'running i %d 0x%x\n' "$i"{,}
else
((j>>=1)); # printf 'new j %d 0x%x\n' "$j"{,}
fi
((k++))
# ((k%10)) || printf 'still running %d 0x%x %d %d' "$i"{,} "$j" "$k"
done
printf "final value of limit %d 0x%x in %d loops\n" "$i"{,} "$k"
Таким образом, предел даты будет:
final value of limit 2147483649 0x80000001 in 64 loops
Удалите символ комментария # , чтобы увидеть, как это делается.
Это похоже на 32-битное число:
$ printf '%d\n%d\n' "$(( (1<<31) + 1 ))" "0x80000001"
2147483649
2147483649
Фактически, это 2 ** 31 + номер дня месяца.
Если мы попробуем с последним днем декабря (измените строку 5 в сценарии выше):
date +'%Y-%m-%d' -d "2017-12-31 $((i+j)) days ago"
Мы получим:
final value of limit 2147483679 0x8000001f in 68 loops
Это 31 выше 2 ** 31
:
$ printf '%d\n%d\n' "$(( (2**31) + 31 ))" "0x8000001f"
2147483679
2147483679
Максимальное значение для целого числа оболочки - i меньше 2, увеличенное до 63:
$ echo $(( (2**63) - 1 ))
9223372036854775807
Мы можем получить десятичное и шестнадцатеричное представление следующим образом:
$ printf '%d %x\n' "$(( (2**63) - 1 ))"{,}
9223372036854775807 7fffffffffffffff
Это максимальное число, представимое в виде целого числа со знаком 64 бита (если ваша система, конечно, 64 бита). Следующее число (просто добавьте один) будет обернуто (переполнено) до отрицательного числа:
$ echo $(( (2**63) ))
-9223372036854775808
$ printf '%d %x\n' "$(( (2**63) ))"{,}
-9223372036854775808 8000000000000000
Это самое отрицательное число для 64-битного целого числа со знаком.
Но более быстрый способ получить тот же результат - использовать сдвиг влево, который делает то же самое, что и умножение числа на два:
$ printf '%d %x\n' "$(( (1<<63) - 1 ))"{,}
9223372036854775807 7fffffffffffffff
Как запустить
infinite_number_loop
в bash?
Простой способ: while:; do ... done
:
let i=0
while :; do
let i++
date +%Y-%m-%d -d "$i day ago" >/dev/null 2>&1 || { echo $i && exit 1; }
done
Если я запустил этот цикл в терминале на моем локальном компьютере, возникнут ли какие-нибудь проблемы?
Нет, пока вы не поймете, что потратили на это слишком много времени.