bash - 如何在变量上使用 grep

bash - 如何在变量上使用 grep

好的,我有一个服务器在特定端口上监听,它接受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 循环来测试正确性……有很多选择

相关内容