我的第一个bash脚本有问题。我在for循环中填充一个数组,当我尝试从中获取一个项目时,我总是得到第一个元素。
for (( i = 0; i < ${#*}; i++ )); do
hash=$(md5 -q ${@:$i:1})
modifiedNames[$i]=${@:$i:1}$hash
done
echo ${modifiedNames[1]}
例如,如果我这样调用我的脚本:./ script.sh file1 file2我得到file1 [file1hash]
提前致谢!
答案 0 :(得分:2)
我认为你的循环表现得很有趣,因为它应该从i = 1开始并转到i = $ {#*}。扩展$ {@:0:1}给出了file1,因此是$ {@:1:1}。
尝试for (( i = 1; i <= ${#*}; i++ ))
答案 1 :(得分:1)
您正在遍历从0开始的arguments数组,这是命令名称。因此,如果您将脚本称为./script.sh file1 file2
,那么:
${@} = array(
[0] = ./script,
[1] = file1,
[2] = file2
)
所以你得到了:
modifiedNamed = array(
[0] = md5(./script),
[1] = md5(file1)
)
您应该将for
循环索引更改为:
for (( i = 1; i <= ${#*}; i++ )); do
答案 2 :(得分:1)
$@
不是真正的数组 - 它是一个shell“特殊参数”,你需要比其他数组更加小心。
您所看到的行为的原因是,当${parameter:length:offset}
为parameter
时,@
语法的确切行为是特殊的,并且行为与如果@
是一个真正的数组,你会得到的行为。
以下是相关文档(粗体强调我的):
${
参数:
偏移:
长度}
...如果参数是@,则结果为长度 位置参数,从偏移量开始。如果参数为@,则结果为 length 位置参数,从 offset 开始。 ...
位置参数是$0
,$1
,$2
,...,因此使用此语法时,其行为就像包含$@
一样脚本名称($0
)以及脚本的参数($1
,$2
,...)。这与"$@"
扩展到"$1" "$2" ...
不一致,但这就是生命。
你应该能够通过创建一个新数组来简化事情(并修复脚本),而不是直接使用$@
,即
new_array=("$@")
for (( i = 0; i < ${#new_array}; i++ )); do
hash=$(md5 -q ${new_array[@]:$i:1})
modifiedNames[$i]=${new_array[@]:$i:1}$hash
done
echo ${modifiedNames[1]}
答案 3 :(得分:0)
实际上, 获取第二个元素,但是你的循环在[0]和[1]中放置相同的值。
我不确定你要做什么,但迭代参数然后为数组保留一个单独的计数器可能会更容易。
n=0
for i in "$@"; do
. . .
n=$(($n + 1))
done