在变量bash中使用变量

在变量bash中使用变量,bash,Bash,您好,我正在尝试更新一个名称中包含变量的变量,但无法确定如何更新: n=6 tot=5 let abc6xyz="$abc6xyz"+"$tot" let abc6xyz="$abc6xyz"+"$tot" echo "abc6xyz $abc6xyz" # Works fine let abc${n}xyz="$abc${n}xyz"+"$tot" echo "abc6xyz $abc6xyz" ++ n=6

您好,我正在尝试更新一个名称中包含变量的变量,但无法确定如何更新:

n=6
tot=5
        let abc6xyz="$abc6xyz"+"$tot"
        let abc6xyz="$abc6xyz"+"$tot"
        echo "abc6xyz $abc6xyz"
#  Works fine
        let abc${n}xyz="$abc${n}xyz"+"$tot"
        echo "abc6xyz $abc6xyz"


++ n=6
++ tot=5
++ let abc6xyz=+5
++ let abc6xyz=5+5
++ echo 'abc6xyz 10'
abc6xyz 10
++ let abc6xyz=6xyz+5
./calc_tots.tst: line 9: let: abc6xyz=6xyz: value too great for base (error token is "6xyz")`enter code here`
++ echo 'abc6xyz 10'
abc6xyz 10

提前感谢您的帮助。

您有几件事对您不利。首先,避免使用
let
,它是一种过时的shell功能。而是使用POSIX算术
(…)

接下来,
$abc${n}xyz
被扩展为
$abc
(未定义)和
${n}xyz
,它是
“6xyz”
,并且不是十进制、八进制或十六进制,因此它对于基数来说是一个太大的数字

在bash中使用POSIX算法,您可以更改脚本,将
(…)
合并为:

#!/bin/bash

n=6
tot=5

    abc6xyz="$tot"
    ((abc6xyz+=tot))        ## use arithmetic operators ((..))
    echo "abc6xyz $abc6xyz"

    ((abc${n}xyz+=tot))           ## then use indirection, e.g. ${!foo}
    echo "abc6xyz $abc6xyz"
示例使用/输出

$ bash -x /tmp/tmp-david/bashindir.sh
+ n=6
+ tot=5
+ abc6xyz=5
+ (( abc6xyz+=tot ))
+ echo 'abc6xyz 10'
abc6xyz 10
+ (( abc6xyz+=tot ))
+ echo 'abc6xyz 15'
abc6xyz 15
$ bash -x /tmp/tmp-david/redir.sh 6
+ (( abc6xyz+=5 ))
+ (( abc6xyz+=5 ))
+ foo=abc6xyz
+ echo 'abc6xyz: 10'
abc6xyz: 10
$ bash -x /tmp/tmp-david/assign.sh 6
+ (( abc6xyz+=5 ))
+ final=10
+ echo 'abc6xyz: 10'
abc6xyz: 10

添加间接或
final=$(…)

在您解释的注释中,您希望将要包含的数字作为
n=
作为脚本的第一个参数(位置参数)。在这种情况下,要在所有添加之后访问总值,请使用间接方式或指定
$(…)
的最终结果

例如,使用间接寻址:

#!/bin/bash

((abc${1}xyz+=5))
((abc${1}xyz+=5))

foo="abc${1}xyz"

echo "abc${1}xyz: ${!foo}"
示例使用/输出

$ bash -x /tmp/tmp-david/bashindir.sh
+ n=6
+ tot=5
+ abc6xyz=5
+ (( abc6xyz+=tot ))
+ echo 'abc6xyz 10'
abc6xyz 10
+ (( abc6xyz+=tot ))
+ echo 'abc6xyz 15'
abc6xyz 15
$ bash -x /tmp/tmp-david/redir.sh 6
+ (( abc6xyz+=5 ))
+ (( abc6xyz+=5 ))
+ foo=abc6xyz
+ echo 'abc6xyz: 10'
abc6xyz: 10
$ bash -x /tmp/tmp-david/assign.sh 6
+ (( abc6xyz+=5 ))
+ final=10
+ echo 'abc6xyz: 10'
abc6xyz: 10
或者最好只分配最后一次算术运算的结果,例如

#!/bin/bash

((abc${1}xyz+=5))
final=$((abc${1}xyz+=5))

echo "abc${1}xyz: $final"
示例使用/输出

$ bash -x /tmp/tmp-david/bashindir.sh
+ n=6
+ tot=5
+ abc6xyz=5
+ (( abc6xyz+=tot ))
+ echo 'abc6xyz 10'
abc6xyz 10
+ (( abc6xyz+=tot ))
+ echo 'abc6xyz 15'
abc6xyz 15
$ bash -x /tmp/tmp-david/redir.sh 6
+ (( abc6xyz+=5 ))
+ (( abc6xyz+=5 ))
+ foo=abc6xyz
+ echo 'abc6xyz: 10'
abc6xyz: 10
$ bash -x /tmp/tmp-david/assign.sh 6
+ (( abc6xyz+=5 ))
+ final=10
+ echo 'abc6xyz: 10'
abc6xyz: 10

你有两件事对你不利。首先,避免使用
let
,它是一种过时的shell功能。而是使用POSIX算术
(…)

接下来,
$abc${n}xyz
被扩展为
$abc
(未定义)和
${n}xyz
,它是
“6xyz”
,并且不是十进制、八进制或十六进制,因此它对于基数来说是一个太大的数字

在bash中使用POSIX算法,您可以更改脚本,将
(…)
合并为:

#!/bin/bash

n=6
tot=5

    abc6xyz="$tot"
    ((abc6xyz+=tot))        ## use arithmetic operators ((..))
    echo "abc6xyz $abc6xyz"

    ((abc${n}xyz+=tot))           ## then use indirection, e.g. ${!foo}
    echo "abc6xyz $abc6xyz"
示例使用/输出

$ bash -x /tmp/tmp-david/bashindir.sh
+ n=6
+ tot=5
+ abc6xyz=5
+ (( abc6xyz+=tot ))
+ echo 'abc6xyz 10'
abc6xyz 10
+ (( abc6xyz+=tot ))
+ echo 'abc6xyz 15'
abc6xyz 15
$ bash -x /tmp/tmp-david/redir.sh 6
+ (( abc6xyz+=5 ))
+ (( abc6xyz+=5 ))
+ foo=abc6xyz
+ echo 'abc6xyz: 10'
abc6xyz: 10
$ bash -x /tmp/tmp-david/assign.sh 6
+ (( abc6xyz+=5 ))
+ final=10
+ echo 'abc6xyz: 10'
abc6xyz: 10

添加间接或
final=$(…)

在您解释的注释中,您希望将要包含的数字作为
n=
作为脚本的第一个参数(位置参数)。在这种情况下,要在所有添加之后访问总值,请使用间接方式或指定
$(…)
的最终结果

例如,使用间接寻址:

#!/bin/bash

((abc${1}xyz+=5))
((abc${1}xyz+=5))

foo="abc${1}xyz"

echo "abc${1}xyz: ${!foo}"
示例使用/输出

$ bash -x /tmp/tmp-david/bashindir.sh
+ n=6
+ tot=5
+ abc6xyz=5
+ (( abc6xyz+=tot ))
+ echo 'abc6xyz 10'
abc6xyz 10
+ (( abc6xyz+=tot ))
+ echo 'abc6xyz 15'
abc6xyz 15
$ bash -x /tmp/tmp-david/redir.sh 6
+ (( abc6xyz+=5 ))
+ (( abc6xyz+=5 ))
+ foo=abc6xyz
+ echo 'abc6xyz: 10'
abc6xyz: 10
$ bash -x /tmp/tmp-david/assign.sh 6
+ (( abc6xyz+=5 ))
+ final=10
+ echo 'abc6xyz: 10'
abc6xyz: 10
或者最好只分配最后一次算术运算的结果,例如

#!/bin/bash

((abc${1}xyz+=5))
final=$((abc${1}xyz+=5))

echo "abc${1}xyz: $final"
示例使用/输出

$ bash -x /tmp/tmp-david/bashindir.sh
+ n=6
+ tot=5
+ abc6xyz=5
+ (( abc6xyz+=tot ))
+ echo 'abc6xyz 10'
abc6xyz 10
+ (( abc6xyz+=tot ))
+ echo 'abc6xyz 15'
abc6xyz 15
$ bash -x /tmp/tmp-david/redir.sh 6
+ (( abc6xyz+=5 ))
+ (( abc6xyz+=5 ))
+ foo=abc6xyz
+ echo 'abc6xyz: 10'
abc6xyz: 10
$ bash -x /tmp/tmp-david/assign.sh 6
+ (( abc6xyz+=5 ))
+ final=10
+ echo 'abc6xyz: 10'
abc6xyz: 10

是的,这会起作用,或者只是使用
((abc${1}xyz+=tot))
来代替。好的,不要添加到我的答案中,注释是可以的。是的,但是注释串在一起作为一行:我收到了一个错误的替换,两次尝试((abc${n}xyz+=tot))回音“abc${n}xyz xyz${abc${n}xyz xyz tst.”/tot:8行:abc${n}xyz abc${xyz,我看到了评论,请不要编辑答案。不要在这里使用间接寻址
${!abc${n}xyz}
,这是一个糟糕的替代。如果需要间接寻址,则它是
somevar=“abc${n}xyz”
,然后使用
${!somevar}
进行访问,但变量
abcNxyz
必须存在。请在原始问题的末尾添加(不要替换)您当前的版本,这样我可以确定我正在解决您当前的问题。是的,这会起作用,或者只使用
((abc${1}xyz+=tot))
。好的,不要添加到我的答案中,评论很好。是的,但是评论被串成了一行:我在两次尝试中都收到了一个错误的替换((abc${n}xyz+=tot))回音“abc${n}xyz${!abc${n}xyz}”。/tot.tst:8行:abc${n}xyz${!abc${n}xyz好的替换,我看到了评论,请不要编辑答案。不要在这里使用间接寻址
${!abc${n}xyz}
,这是一个糟糕的替代。如果需要间接寻址,则它是
somevar=“abc${n}xyz”
,然后使用
${!somevar}
进行访问,但变量
abcNxyz
必须存在。请在原始问题末尾添加(不要替换)您当前的版本,这样我可以确定我正在解决您当前的问题。