Итак, у меня есть сервер, прослушивающий определенный порт, который принимает 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

Но по какой-то причине это тоже не сработало

2 ответа2

2

Часто немедленным ответом будет «использовать $(...) ». Но, следуя вашему примеру, это будет неправильный ответ, потому что это будет путать вывод с состоянием выхода - вы сравниваете что-то с 0, так что «что-то» должно быть состоянием выхода.

Примечание: вы также путаете ввод с аргументами команды. Когда grep задаются дополнительные аргументы, он ожидает, что они будут файлами, а не прямыми строками. Вам нужно echo "$output" | grep -q "Correct" если у вас есть строковая переменная без соответствующего файла.

Вернуться к состоянию выхода. Статус хранится в $? переменная (пока следующая команда не перезапишет это):

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 - вы можете напрямую проверить содержимое переменной. В настоящее время вы проверяете, встречается ли слово "Исправить" где-либо в строке - это можно переопределить, используя bash [[ wildcard match:

if [[ $output == *Correct* ]]; then

(То же самое можно сделать в чистом sh, используя case $output in ... )

И если строка всегда точно соответствует слову "Правильно" или нет, это еще проще:

if [[ $output == Correct ]]; then

if [ "$output" = Correct ]; then
0

Вы также можете использовать список AND, чтобы быстро проверить состояние выхода:

Списки AND и OR являются последовательностями одного или нескольких конвейеров, разделенных символами && и || управляющие операторы соответственно. Списки AND и OR выполняются с левой ассоциативностью. Список AND имеет вид

command1 && command2

Команда2 выполняется тогда и только тогда, когда команда1 возвращает нулевое состояние выхода.

(от 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 для выхода из цикла, если есть только один "правильный" номер. Или, может быть, время или пока цикл, который проверяет правильность ... много вариантов

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .