Иногда я запускаю команду ping (в GNU/Linux), и она не останавливается сразу после нажатия Ctrl-c .

В моем понимании ctrl-c отправляет SIGINT. Каковы возможные причины, по которым команда ping не завершается немедленно?

Что я могу сделать, чтобы он всегда выходил мгновенно?

1 ответ1

3

Программы могут привязывать пользовательские обработчики к сигналу SIGINT, например, для выполнения действий по очистке. Вы можете наблюдать это поведение с помощью этого сценария оболочки, который связывает обработчик, используя trap:

#!/bin/bash
trap "echo Caught!" SIGINT SIGTERM

while true
do sleep 60
done

Чтобы мгновенно убить интерактивную программу, вы можете либо выполнить kill -9 <PID> в другой оболочке, либо использовать ctrl-Z, чтобы приостановить программу, а затем уничтожить ее:

❯ /tmp/test.sh    # Our test script with trap
^CCaught!         # Ctrl-c doesn't work
^Z                # Suspend the process
[1]  + 11713 suspended  /tmp/test.sh
❯ kill -9 %1
[1]  + 11713 killed

Здесь я использую% 1, чтобы получить pid этого первого фонового процесса, который является сценарием, потому что у меня нет других фоновых процессов в этом примере. Вы также можете использовать PID процесса напрямую для оболочек, которые не поддерживают синтаксис% 1.


И это то, что делает ping, просто посмотрите на исходный код: в основной функции вызывается setup, который устанавливает обработчики сигналов, включая SIGINT. SIGINT связан с sigexit, который устанавливает флаг, чтобы уведомить основной цикл о том, что ping должен выйти. Этот флаг отмечен только в двух местах. Я предполагаю, что один из системных вызовов, используемых там, блокирует или требует некоторого времени для возврата, поэтому флаг никогда не будет проверен или только после задержки.

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