linux shell变量追加,在bash中,如何增加一个变量?

问题描述

我试图用var=$var+1和var=($var+1)增加一个数字变量,但没有成功。该变量是一个数字,但bash似乎将其作为字符串读取。

Bash版本4.2.45(1) – 在Ubuntu 13.10上发布(x86_64-pc-linux-gnu)。

最佳解决方案

在bash中增加一个变量的方法不止一种,但你尝试的是不正确的。

您可以使用例如算术扩展:

var=$((var+1))

((var=var+1))

((var+=1))

((var++))

或者你可以使用let:

let "var=var+1"

let "var+=1"

let "var++"

次佳解决方案

var=$((var + 1))

bash中的算术使用$((...))语法。

第三种解决方案

各种选项的性能分析

感谢Radu Rădeanu’s answer,它提供了以下方法来在bash中增加一个变量:

var=$((var+1))

((var=var+1))

((var+=1))

((var++))

let "var=var+1"

let "var+=1"

let "var++"

还有其他的方法。例如,查看关于这个问题的其他答案。

let var++

var=$((var++))

((++var))

{

declare -i var

var=var+1

var+=1

}

{

i=0

i=$(expr $i + 1)

}

有这么多的选择导致这两个问题:

他们之间有性能差异吗?

如果是的话,哪个表现最好?

增量性能测试代码:

#!/bin/bash

# To focus exclusively on the performance of each type of increment

# statement, we should exclude bash performing while loops from the

# performance measure. So, let's time individual scripts that

# increment $i in their own unique way.

# Declare i as an integer for tests 12 and 13.

echo > t12 'declare -i i; i=i+1'

echo > t13 'declare -i i; i+=1'

# Set i for test 14.

echo > t14 'i=0; i=$(expr $i + 1)'

x=100000

while ((x--)); do

echo >> t0 'i=$((i+1))'

echo >> t1 'i=$((i++))'

echo >> t2 '((i=i+1))'

echo >> t3 '((i+=1))'

echo >> t4 '((i++))'

echo >> t5 '((++i))'

echo >> t6 'let "i=i+1"'

echo >> t7 'let "i+=1"'

echo >> t8 'let "i++"'

echo >> t9 'let i=i+1'

echo >> t10 'let i+=1'

echo >> t11 'let i++'

echo >> t12 'i=i+1'

echo >> t13 'i+=1'

echo >> t14 'i=$(expr $i + 1)'

done

for script in t0 t1 t2 t3 t4 t5 t6 t7 t8 t9 t10 t11 t12 t13 t14; do

line1="$(head -1 "$script")"

printf "%-24s" "$line1"

{ time bash "$script"; } |& grep user

# Since stderr is being piped to grep above, this will confirm

# there are no errors from running the command:

eval "$line1"

rm "$script"

done

结果:

i=$((i+1)) user 0m0.992s

i=$((i++)) user 0m0.964s

((i=i+1)) user 0m0.760s

((i+=1)) user 0m0.700s

((i++)) user 0m0.644s

((++i)) user 0m0.556s

let "i=i+1" user 0m1.116s

let "i+=1" user 0m1.100s

let "i++" user 0m1.008s

let i=i+1 user 0m0.952s

let i+=1 user 0m1.040s

let i++ user 0m0.820s

declare -i i; i=i+1 user 0m0.528s

declare -i i; i+=1 user 0m0.492s

i=0; i=$(expr $i + 1) user 0m5.464s

结论:

当$i被声明为整数时,看起来bash在执行i+=1时速度最快。 let语句看起来特别慢,而expr是最慢的,因为它不是内建的。

第四种方案

还有这个:

var=`expr $var + 1`

注意空间并且’不’

虽然Radu的答案和评论非常详尽且非常有帮助,但它们是bash-specific。我知道你确实特别询问了bash,但是我认为自从我在uCLinux下的busybox中使用sh来做同样的事情时,我发现了这个问题。这种便携式超越bash。

第五种方案

如果你将$var声明为一个整数,那么你第一次尝试的东西实际上会工作:

$ declare -i var=5

$ echo $var

5

$ var=$var+1

$ echo $var

6

第六种方案

所有答案中都缺少一种方法 – bc

$ VAR=7

$ bc <<< "$VAR+2"

9

$ echo $VAR

7

$ VAR=$( bc <<< "$VAR+1" )

$ echo $VAR

8

bc由POSIX标准指定,因此应该在所有版本的Ubuntu和POSIX-compliant系统上提供。为便于携带,<<

第七种方案

所有默认变体(let,(())等)均存在返回码1问题。这经常会造成麻烦,例如,在使用set -o errexit的脚本中。这是我用来防止错误代码1从数学表达式评估到0;

math() { (( "$@" )) || true; }

math a = 10, b = 10

math a++, b+=2

math c = a + b

math mod = c % 20

echo $a $b $c $mod

#11 12 23 3

参考资料

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值