我正在编写一个搜索文件的脚本,获取然后存储到变量中的信息,并执行我使用这些变量作为数据创建的程序。我实际上已经完成了所有这些工作,但我需要更进一步:
我目前拥有的是
#!/bin/sh
START=0
END=9
LOOP=10
PASS=0
for i in $(seq 0 $LOOP)
do
LEN=$(awk '/Len =/ { print $3; exit;}' ../../Tests/shabittestvectors/SHA1ShortMsg.rsp)
MSG=$(awk '/Msg =/ { print $3; exit; }' ../../Tests/shabittestvectors/SHA1ShortMsg.rsp)
MD=$(awk '/MD =/ { print $3; exit; }' ../../Tests/shabittestvectors/SHA1ShortMsg.rsp)
echo $LEN
echo $MSG
MD=${MD:0:-1}
CIPHER=$(./cyassl hash -sha -i $MSG -l $LEN)
echo $MD
echo $CIPHER
if [ $MD == $CIPHER ]; then
echo "PASSED"
PASS=$[PASS + 1]
echo $PASS
fi
done
if [ $PASS == $[LOOP+1] ]; then
echo "All Tests Successful"
fi
输入文件如下所示:
Len = 0
Msg = 00
MD = da39a3ee5e6b4b0d3255bfef95601890afd80709
Len = 1
Msg = 00
MD = bb6b3e18f0115b57925241676f5b1ae88747b08a
Len = 2
Msg = 40
MD = ec6b39952e1a3ec3ab3507185cf756181c84bbe2
所有程序现在都在做,读取变量的第一个实例并在那里循环。我希望使用START
和END
来确定它检查文件的行,然后在每次循环时递增它们以获取变量名的其他实例,但所有到目前为止,我的尝试都没有成功。有什么想法吗?
编辑:输出应该看起来像,提供我的程序" ./ cyassl"按原样运作
0
00
da39a3ee5e6b4b0d3255bfef95601890afd80709
da39a3ee5e6b4b0d3255bfef95601890afd80709
PASSED
1
00
bb6b3e18f0115b57925241676f5b1ae88747b08a
bb6b3e18f0115b57925241676f5b1ae88747b08a
PASSED
2
40
ec6b39952e1a3ec3ab3507185cf756181c84bbe2
ec6b39952e1a3ec3ab3507185cf756181c84bbe2
PASSED
etc.
答案 0 :(得分:3)
无需对输入文件进行多次传递。
#!/bin/sh
exec < ../../Tests/shabittestvectors/SHA1ShortMsg.rsp
status=pass
awk '{print $3,$6,$9}' RS= | {
while read len msg md; do
if test "$(./cyassl hash -sha -i $msg -l $len)" = "$md"; then
echo passed
else
status=fail
fi
done
test "$status" = pass && echo all tests passed
}
awk将从stdin读取(exec从文件重定向;我个人会跳过该行并适当地调用者直接输入)并将输入分成每个段落的记录。 A&#34;段落&#34;这意味着记录由空行分隔(行必须是真正的空白,并且不能包含空格)。然后,Awk解析每条记录并在一行上打印第3,第6和第9个字段。这有点脆弱,但对于显示的输入,这些字段分别表示长度,消息和md散列。所有awk正在做的是重新排列输入,使其每行一个记录。一旦数据具有更易读的格式,子shell就会一次读取一行数据,将其解析为名为&#34; len&#34;,&#34; msg&#34;和&#34;的变量。 MD&#34 ;. do循环每行输入一次,喷出相当冗长的消息&#34;传递&#34;它运行的每个测试(我会删除它,但保留它在这里与原始脚本保持一致),并在任何测试失败时设置状态。必须使用大括号来确保在do循环终止后保留变量状态的值。
答案 1 :(得分:2)
以下代码,
inputfile="../../Tests/shabittestvectors/SHA1ShortMsg.rsp"
while read -r len msg md
do
echo got: LEN:$len MSG:$msg MD:$md
#cypher=$(./cyassl hash -sha -i $msg -l $len)
#continue as you wish
done < <(perl -00 -F'[\s=]+|\n' -lE 'say qq{$F[1] $F[3] $F[5]}' < "$inputfile")
输入数据,产生:
got: LEN:0 MSG:00 MD:da39a3ee5e6b4b0d3255bfef95601890afd80709
got: LEN:1 MSG:00 MD:bb6b3e18f0115b57925241676f5b1ae88747b08a
got: LEN:2 MSG:40 MD:ec6b39952e1a3ec3ab3507185cf756181c84bbe2
答案 2 :(得分:1)
如果输入数据符合您的要求,您可以使用简化的bash
:
#!/bin/bash
LOOP=10
PASS=0
FILE='../../Tests/shabittestvectors/SHA1ShortMsg.rsp'
for (( I = 1; I <= LOOP; ++I )); do
read -r LEN && read -r MSG && read -r MD || break
echo "$LEN"
echo "$MSG"
MD=${MD:0:-1}
CIPHER=$(exec ./cyassl hash -sha -i "$MSG" -l "$LEN")
echo "$MD"
echo "$CIPHER"
if [[ $MD == "$CIPHER" ]]; then
echo "PASSED"
(( ++PASS ))
fi
done < <(exec awk '/Len =/,/Msg =/,/MD =/ { print $3 }' "$FILE")
[[ PASS -eq LOOP ]] && echo "All Tests Successful."
请确保不要将其作为sh
运行,例如sh script.sh
。 bash script.sh
最有可能。