Я хочу отправить SIGKILL, если в выводе команды отображается определенное ключевое слово. Например, если ввести следующую команду:
ubuntu@ip-172-31-24-250:~$ ping 8.8.8.8
PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data.
64 bytes from 8.8.8.8: icmp_seq=1 ttl=109 time=0.687 ms
64 bytes from 8.8.8.8: icmp_seq=2 ttl=109 time=0.704 ms
64 bytes from 8.8.8.8: icmp_seq=3 ttl=109 time=0.711 ms
64 bytes from 8.8.8.8: icmp_seq=4 ttl=109 time=0.809 ms
64 bytes from 8.8.8.8: icmp_seq=5 ttl=109 time=0.727 ms
64 bytes from 8.8.8.8: icmp_seq=6 ttl=109 time=0.835 ms
^C
Увидев вывод "icmp_seq=6", я бы хотел, чтобы команда автоматически останавливалась. Я знаю, что пинг 8.8.8.8 -с 6 будет иметь те же результаты, но это просто для примера.





Один из способов сделать это — перенаправить вывод команды в файл, а затем настроить цикл для grep файла для конкретной строки, которую вы хотите. Если grep успешно, то завершите цикл и завершите процесс. Такой сценарий для ping может выглядеть так:
В ЭТОМ ОШИБКА
ping www.google.com > output 2> error &
while [ true ]; do
grep "icmp_seq=6" output
if [ $? -eq 0 ]; then
break
fi
done
echo "sequence found, killing program"
pid=`pgrep ping` # get the PID of ping so we can kill it
kill -9 ${pid}
Обновлять: Мне только что пришло в голову, что у этого сценария есть недостаток, заключающийся в том, что он будет работать бесконечно, если искомый текст никогда не появится (и на самом деле он будет продолжать работать бесконечно даже после завершения программы-кандидата или после того, как программа умрет сразу при запуске). Итак, вот улучшенный скрипт, учитывающий все это:
ping www.google.com > output 2> error & # the & makes the command a background process so execution of other commands isn't blocked
pid=`pgrep ping`
while [ ! -z ${pid} ]; do # check if pid contains anything - if so, the ping command is still running
grep "icmp_seq=6" output
if [ $? -eq 0 ]; then
echo "sequence found, killing program"
kill -9 ${pid}
exit 0
fi
pid=`pgrep ping`
done
echo "Sequence not found"
Обновление оптимизации: Поскольку у меня обсессивно-компульсивное расстройство, этот скрипт может застрять, если будет много вывода, потому что grep должен просеять все это. Таким образом, мое предложение по оптимизации будет состоять в том, чтобы использовать tail -1 output, а затем направить вывод в grep, что приведет к следующему сценарию:
ping www.google.com > output 2> error & # the & makes the command a background process so execution of other commands isn't blocked
pid=`pgrep ping`
while [ ! -z ${pid} ]; do # check if pid contains anything - if so, the ping command is still running
tail -1 output | grep "icmp_seq=6"
if [ $? -eq 0 ]; then
echo "sequence found, killing program"
kill -9 ${pid}
exit 0
fi
pid=`pgrep ping`
done
echo "Sequence not found"
@ChristianTapia Это хорошее предложение, но внутри цикла оно не сработает.
Не могли бы вы попробовать следующее:
#!/bin/bash
ping 8.8.8.8 | while IFS= read -r line; do
echo "$line"
[[ $line =~ icmp_seq=6 ]] && kill -9 $(pidof ping)
done
Это намного более чистая версия того, что я написал, и у нее есть бонус, позволяющий избежать создания файла.
Я не эксперт, но, возможно, чтобы избежать конфликтов с другими
ping, работающими параллельно, можно было бы использоватьpid=$!.