bash:local:`0':不是有效的标识符

时间:2015-08-31 12:42:22

标签: bash

当我打电话给例如加密HI时,结果是:

bash: local: `0': not a valid identifier
bash: local: `1': not a valid identifier

以下是代码:

#!/bin/bash
encrypt(){
    local s="$1";
    local lenght=${#s};
    local i=0
    while [ $i -lt $lenght ]
    do
        local j=1
        local letter=expr substr $s $i $j;
        letterToNumber $letter;
        echo $number;
        i=$[$i+$j];
    done
}

3 个答案:

答案 0 :(得分:4)

 > local letter=expr substr $s $i $j;

看起来这是你的问题。这是一个新手的错误,显然你打算写

local letter=$(expr substr "$s" "$i" "$j")

新手有时似乎很难使用shell语法。 shell简单地从左边标记你的命令;不包含=的第一个标记是关键字或命令,并且(在一般情况下)其余标记只是作为参数传递给该命令的文本。因此letter=expr substr会将值expr分配给变量letter并尝试运行命令substr;并且local foo=bar baz quux会将变量foobazquux声明为本地变量,并在我们到达时将值bar分配给foo

在现代shell脚本中,很少使用expr。 Bash有一个内置的子串运算符; ${s:$i-1:$j}

encrypt () {
    for((i=0; i<${#1}; ++i)); do
        letterToNumber "${1:i:1}"
    done
}

(我猜你也想说number=$(letterToNumber "${1:i:1}"); echo "$number",但那只是useless use of echo。)

答案 1 :(得分:1)

tripleee是对的。

虽然我没有你的letterToNumber功能/程序,但我认为还有其他两个问题:

#!/bin/bash
#set -v # always handy
#set -e # handy too

encrypt(){
    local s="$1";
    local lenght=${#s};
    local i=1 # <--------  start at 1, not 0
    while [ $i -le $lenght ] # <-------- le, not lt
    do
        local j=1
        local letter=$(expr substr $s $i $j);
        echo letter $letter
        #letterToNumber $letter;
        echo $number;
        i=$[$i+$j];
    done
}

encrypt HELLO

输出:

$ ./foobar.sh 
letter H

letter E

letter L

letter L

letter O

答案 2 :(得分:1)

而不是# Insert this line before `local s="$1";` or anywhere else before while loop local letter # Inside the "while loop"... letter=${s:$i:$j} ,这是不正确的(知道原因,请参阅tripleee的答案),你可以这样做:

# Replace `local i=0` with this line:
local -i i=0 j=1
# i=i+j . Note: you dont need "$" here!
i+=j

要计算i = i + j,最好使用更短的(比平均值)BASH内部数学语法:

encrypt () {
            local s="$1" letter length=${#s}
            local -i i=0 j=1
            for ((; i<length; i+=j )); do
                    letter=${s:$i:$j}
                    letterToNumber "$letter"
                    echo $number
            done
            return 0
}

最后整体加密功能代码为:

{{1}}

这段代码可能会被最简单的单行代码所取代,但是......你还没有回答(还有)如何做到这一点:)