У меня проблема с передачей таких сигналов, как SIGKILL, SIGINT, SIGTERP, в сценарий bash, который использует tcpdump.
Основной вопрос - как убить процесс tcpdump (дочерний), если homeone убивает основной скрипт.
У меня есть следующий скрипт (часть):
#for log
function log {
echo "$CURRENT_DATE_TIME $1" >> "${LOG_DIR}/${MAIN_LOG_FILE}"
echo "$1"
}
#to start tcpdump
function start_tcpdump {
${TCPDUMP} ${TCPDUMP_ARGS} ${TCPDUMP_LOG_FILE} ${TCPDUMP_SMPP_PDU} &
TCPDUMP_PID=$!
log "Start tcpdump PID: ${TCPDUMP_PID}"
sleep 60
}
#to stop tcpdump
function stop_tcpdump {
kill -s 2 ${TCPDUMP_PID}
log "Stop tcpdump PID ${TCPDUMP_PID}"
TCPDUMP_PID=0
}
#check if process exists
function check_tcpdump {
if [[ ${TCPDUMP_PID} -ne 0 ]] && [[ -e /proc/${TCPDUMP_PID} ]] && kill -s 0 "${TCPDUMP_PID}" 2>/dev/null
then
log "Checking tcpdump. Already started PID ${TCPDUMP_PID}"
return 1
else
log "Checking tcpdump. Not started"
return 0
fi
# [[ ${TCPDUMP_PID} -ne 0 ]] && [[ -e /proc/${TCPDUMP_PID} ]] && kill -s 0 "${TCPDUMP_PID}" 2>/dev/null
}
#main function here
function main {
log "#####INIT#####"
start_tcpdump
trap stop_tcpdump SIGINT SIGKILL SIGTERM SIGSTOP
check_tcpdump
stop_tcpdump
}
main
Но если кто-то забудет и убьет скрипт:
$ sh ./gms_trace_smpp.sh
$ kill $pid
процесс, который управляет дампом tcp, все еще существует.
Я хотел бы вызвать функцию stop_tcpdump и убить дочерний процесс tcpdump, если скрипт получает один из сигналов (SIGINT SIGKILL SIGTERM SIGSTOP).
И сделали это с помощью ловушки:
trap stop_tcpdump SIGINT SIGKILL SIGTERM SIGSTOP
Но это не работает.
Кто-нибудь знает, как обрабатывать сигнал и убивать дочерний процесс (tcpdump), когда кто-то убивает основной скрипт?
Вы должны взглянуть на Что делает set -o errtrace
в сценарии оболочки?
SIGKILL и SIGSTOP не могут быть перехвачены!
Если SIGKILL и SIGSTOP не могут быть перехвачены, как я могу также остановить процесс tcpdump в сценарии, если кто-то убьет этот сценарий? Может быть, у вас есть идея.
Некоторые сигналы обычно не могут быть заблокированы. Хотя есть способы сделать процесс неубиваемым, это сложная, плохая идея и, вероятно, бесполезная.
Одним из простых вариантов является добавление задания at
для выполнения очистки, если оно обнаружит, что скрипт завершился (или он всегда может выполнить части check_tcpdump
и stop_tcpdump
).
Еще один более сложный вариант — переплести скрипт с другим — они могут контролировать друг друга и выполнять очистку при завершении одного из них (ср. Робин Гуд и монах Так)
Из
man trap
«Реализации могут разрешать имена с префиксом SIG», но не могут. Удалите префиксы SIG из спецификации trap. | Если вы хотите выйти после получения сигнала, вызовитеexit
в обработчике trap.