我们可以在 shell 脚本函数中使用算术运算:
function mess
{
if (( "$1" > 0 )) ; then
total=$1
else
total=100
fi
tail -$total /var/adm/messages | more
}
我尝试对函数 args 进行算术运算:
#!/bin/bash
byte="Bytes"
kilo="KB"
mega="MB"
giga="GB"
function bytesToUnites() {
if (( "$1" < 1000 ))
then
echo $1" "$byte
elif (( $1 < 1000000 ))
then
let $1/=1000
echo $1" "$kilo
fi
}
bytesToUnites 28888
但我收到这个错误:
line 12: let: 28888/=1000: attempted assignment to non-variable (error token is "/=1000")
28888 KB
我怎样才能解决这个问题?
答案1
答案2
为位置参数赋值的唯一方法bash
是通过set
内置函数:
set a b
分配a
给$1
和b
to $2
(请注意,它重置了整个位置参数列表,因此$3
, $4
... 丢失)。
所以在这里,你可以这样做:
set -- "$(($1 / 1000))"
$1
将除以 1000的值赋给$1
。
相比之下,使用zsh
(更高级的类似 Bourne 的 shell,不是 GNU 项目的一部分,在所有 Unices 上都有,但通常不是默认情况下),您可以分配单独的位置参数,例如:
1=$(($1 / 1000))
或者:
argv[1]=$(($1 / 1000))
或者:
(( argv[1] /= 1000 ))
($argv
是一个与位置参数相关的特殊数组)
你仍然不能这样做:
let 1/=1000
(( 1/=1000 ))
尽管。
zsh
还支持浮点运算,所以你可以这样做:
((argv[1] /= 1000.))
(使用浮点常量 (1000.) 强制进行浮点运算)。
您可能希望将其显示为:
printf "%.2f$kilo\n" $1
答案3
对于我的两分钱,我建议您使用%
模数。您只需沿着单元列表向上移动即可,并在每一步中保存剩余部分。这里:
(
gb=$(((mb=(kb=1024*(b=1))*kb)*kb)) #define units
set -- 8934752983457 #your $1 - just a random test
for u in '' k m g #this part is neat
do [ $((c=$1/${u}b)) -ge 1 ] || break #math eval varnames
[ "$u" != g ] && c=$(($c%$kb)) #if not yet g only save %
set -- $(($1-$c)) "$c${u}b${2:+.$2}" #decrement $1 - build $2
done ; shift #done - toss $1
IFS=. ; printf %s\\n $* #split $2 andd print
)
输出
8321gb
140mb
454kb
417b