当我打电话给例如加密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
}
答案 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
会将变量foo
,baz
和quux
声明为本地变量,并在我们到达时将值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}}
这段代码可能会被最简单的单行代码所取代,但是......你还没有回答(还有)如何做到这一点:)