好的,我有一个服务器在特定端口上监听,它接受PIN码并以“正确”或“错误”的消息回复。
我创建了以下脚本来尝试所有可能的 3 位密码:
i=0
While [ $i -le 999]
do
echo $i |nc localhost port
((i++))
done
当我执行此操作时,我得到以下输出:
Wrong
Wrong
Wrong
Wrong
Correct
Wrong
Wrong
...
我的问题是,我如何修改此脚本以便它使用 grep 仅显示“正确”的消息?
我尝试了以下操作:
i=0
While [ $i -le 999]
do
output=$(echo $i |nc localhost port)
if [ grep -q "Correct" $output -eq 0]
then
echo "the right pin is $i"
((i++))
done
但由于某种原因,它也没有起作用
答案1
通常,直接的答案是“使用$(...)
”。但按照你的例子,这将是错误的答案,因为它会让人困惑输出与退出状态– 您正在将某物与 0 进行比较,因此“某物”必须是退出状态。
附注:你也让人困惑输入和命令参数echo "$output" | grep -q "Correct"
。当 grep 被赋予附加参数时,它期望它们是文件,而不是直接字符串。如果您只有一个字符串变量而没有相应的文件,则需要。
返回退出状态。状态存储在变量中$?
(直到下一个命令覆盖它):
echo $output | grep -q "Correct"
if [ $? -eq 0 ]; then
echo "OK!"
fi
或者使用 bash 的语法:
echo $output | grep -q "Correct"
if (( $? == 0 )); then
echo "OK!"
fi
但是,这有点多余,因为将退出状态与 0 进行比较if
一直都在做。这[
不是一个特殊的语法元素——它本身只是一个命令,如果比较成功,它会以 0 退出。您也可以使用任何其他命令代替它:
if echo $output | grep -q "Correct"; then
echo "OK!"
fi
最后,你真的不需要grep这里根本没有任何东西——您可以直接检查变量的内容。您当前正在检查的是单词“Correct”是否出现在字符串中的任何位置——可以使用 bash 的[[
通配符匹配重新实现:
if [[ $output == *Correct* ]]; then
(在纯 sh 中使用 可以完成相同的操作case $output in ...
。)
如果字符串始终是确切地无论“正确”与否,这更简单:
if [[ $output == Correct ]]; then
if [ "$output" = Correct ]; then
答案2
您还可以使用 AND 列表来快速检查退出状态:
AND 和 OR 列表是一个或多个管道的序列,分别由 && 和 || 控制运算符分隔。AND 和 OR 列表以左结合性执行。AND 列表的形式为
command1 && command2
当且仅当 command1 返回退出状态零时,才会执行 command2。
(从
man bash
)
因此在这种情况下,你可能希望在 while 循环中这样做:
echo $i |nc localhost port | grep -q "Correct" && echo "OK!"
或者可能是类似
for i in {1..999}
do
echo $i |nc localhost port | grep -q "Correct" && echo "OK!"
done
break
如果只有一个“正确”数字,则可选择退出循环。或者可能是 while 或 till 循环来测试正确性……有很多选择