Запретить отправку CTRL + C процессу, вызванному из сценария Bash - PullRequest
0 голосов
/ 13 мая 2019

Вот упрощенная версия кода, над которым я работаю:

#!/bin/bash

term() {
  echo ctrl c pressed!
  # perform cleanup - don't exit immediately
}
trap term SIGINT

sleep 100 &
wait $!

Как видите, я бы хотел перехватить CTRL + C / SIGINT и обработать их с помощью пользовательской функции для выполнения какой-либо операции очистки, а не для немедленного выхода.

Однако, после нажатия CTRL + C , на самом деле кажется, что, хотя я вижу, что ctrl c pressed! отражается, как и ожидалось, команда wait также убивается чего бы я не хотел (часть моей операции очистки убивает sleep чуть позже, но сначала делает некоторые другие вещи). Есть ли способ предотвратить это, то есть остановить CTRL + C вход, отправляемый на команду wait?

Ответы [ 2 ]

2 голосов
/ 13 мая 2019

Вы можете запретить процессу, вызываемому из сценария Bash, получать sigint, сначала проигнорировав сигнал с помощью trap:

#!/bin/bash
# Cannot be interrupted
( trap '' INT; exec sleep 10; )

Однако только родительский процесс может ожидать своего потомка, поэтому wait является встроенной оболочкой, а не новым процессом. Следовательно, это не относится.

Вместо этого просто перезапустите wait после его прерывания:

#!/bin/bash
n=0
term() {
  echo "ctrl c pressed!"
  n=$((n+1))
}
trap term INT


sleep 100 &

while
  wait "$!"
  [ "$?" -eq 130 ]   # Sigint results in exit code 128+2
do
  if [ "$n" -ge 3 ]
  then
    echo "Jeez, fine"
    exit 1
  fi
done
0 голосов
/ 14 мая 2019

В итоге я использовал измененную версию того, что предложил @thatotherguy:

#!/bin/bash

term() {
  echo ctrl c pressed!
  # perform cleanup - don't exit immediately
}
trap term SIGINT

sleep 100 &
pid=$!

while ps -p $pid > /dev/null; do
  wait $pid
done

Это проверяет, работает ли еще процесс, и, если да, запускает wait снова.

...