bash: арифметические выражения внутри переменных - PullRequest
0 голосов
/ 20 июня 2019

У меня есть простой код для назначения переменных в цикле на основе простого арифметического равенства

 # assign initial value
    restr_start='25'
    # assign a new variable, which is a number that will decrease initial value by 5
    # keeping always the value of previous variable as restr_prev 
    for step in {1..4}; do
      let "restr=(${restr_start} - (5 * ${step}))"
      let "restr_prev=(${restr} + (5 * ${step}))"
      echo this is $restr current restart
      echo this is $restr_prev previous restart
    done

Из этого скрипта я ожидаю получить:

this is 20 current restart
this is 25 previous restart
this is 15 current restart
this is 20 previous restart
this is 10 current restart
this is 15 previous restart
this is 5 current restart
this is 10 previous restart

однако, что у меня на самом деле есть

this is 20 current restart
this is 25 previous restart
this is 15 current restart
this is 25 previous restart
this is 10 current restart
this is 25 previous restart
this is 5 current restart
this is 25 previous restart

почему $ restr_prev обычно не изменяется? как я могу изменить код, например, использовать что-то вместо let ?

1 Ответ

2 голосов
/ 20 июня 2019

Это скорее математическая проблема, чем проблема с вашим кодом bash. Посмотрите на формулу для $restr_prev:

restr_prev= ${restr} + (5 * ${step})

Для шага 1 формула рассчитывается до 20 + 5 * 1 = 25, для шага 2 формула приводит к 15 + 5 * 2 = 25 и так далее ...

Чтобы получить ожидаемые результаты, вам просто нужно добавить 5 к значению restr. Следовательно, соответствующая строка в вашем скрипте должна выглядеть так:

let "restr_prev=(${restr} + 5)"

Как уже было предложено в комментариях, вы должны использовать $((expression)) для арифметического расширения вместо let, так как последнее является встроенным в bash и не охватывается стандартом POSIX . Обращение с предложениями приводит к следующему коду:

#!/bin/bash

# assign initial value
restr_start='25'
# assign a new variable, which is a number that will decrease initial value by 5
# keeping always the value of previous variable as restr_prev 
for step in {1..4}; do
    restr=$((restr_start - (5 * step)))
    restr_prev=$((restr + 5))
    echo "this is $restr current restart"
    echo "this is $restr_prev previous restart"
done
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...