【问题标题】:bash: arithmetic expressions inside of variablesbash:变量内的算术表达式
【发布时间】:2019-06-20 09:43:45
【问题描述】:

我有一个简单的代码来基于简单的算术等式在循环中分配变量

 # 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

【问题讨论】:

  • 数学看起来正确!你有什么问题?
  • @Inian 不,restr_prev 的公式不正确。请查看我的答案以获得更准确的解释。
  • @EduardItrich:我的意思是,对于代码,OP 产生的输出是正确的。对于不同的输出,需要更改代码
  • 不要使用let;在存在 POSIX 算术表达式的情况下,它已经过时了。 restr=$((restr_start - 5*step)).
  • 或者更好(但不是 POSIX):(( restr = restr_start - 5 * step )) - 请注意,在这两个示例中,变量名称中都省略了美元符号和花括号。

标签: bash loops variables equation


【解决方案1】:

这是一个数学问题,而不是 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)"

正如 cmets 中已经建议的那样,您应该使用 $((expression)) 而不是 let 进行算术扩展,因为后者是内置的 bash 并且不包含在 POSIX standard 中。听取建议导致以下代码:

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

【讨论】:

  • 查看 chepner 和我的 cmets 关于算术公式的问题。始终引用您的变量(例如,echo 命令)。
  • 为什么 restr_prev=$((restr + 5)) 比 let "restr_prev=(${restr} + 5)" 好?
  • 请看我修改后的答案,它解决了您的问题。
猜你喜欢
  • 2023-03-20
  • 2015-10-27
  • 2011-01-25
  • 1970-01-01
  • 2011-01-31
  • 1970-01-01
  • 2020-01-11
  • 1970-01-01
  • 2016-10-17
相关资源
最近更新 更多