Установить ловушку в bash для другого процесса с известным PID - PullRequest
5 голосов
/ 07 марта 2011

Мне нужно установить ловушку для процесса bash, который я запускаю в фоновом режиме. Фоновый процесс может выполняться очень долго, и его PID сохраняется в определенном файле.

Теперь мне нужно установить ловушку для этого процесса, поэтому, если он завершится, PID-файл будет удален.

Есть ли способ, которым я могу это сделать?

РЕДАКТИРОВАТЬ # 1

Похоже, я не был достаточно точен с описанием проблемы. У меня есть полный контроль над всем кодом, но у меня есть длительный фоновый процесс:

cat /dev/random >> myfile&

Когда я сейчас добавлю ловушку в начале скрипта, в котором находится этот оператор, $$ будет PID этого более крупного скрипта, а не этого небольшого фонового процесса, который я начинаю здесь.

Так, как я могу установить ловушки для этого фонового процесса?

Ответы [ 4 ]

2 голосов
/ 07 марта 2011
(./jobsworthy& echo $! > $pidfile; wait; rm -f $pidfile)&
disown
0 голосов
/ 17 марта 2013

Вы можете запустить длительный фоновый процесс в явной подоболочке, как уже показано в ответе Петеша, и установить ловушку внутри этой конкретной подоболочки для обработки выхода из вашего продолжительного фонового процесса. Эта родительская оболочка остается незатронутой этой ловушкой подоболочки.

(
trap '
  trap - EXIT ERR
  kill -0 ${!} 1>/dev/null 2>&1 && kill ${!}
  rm -f pidfile.pid
  exit
' EXIT QUIT INT STOP TERM ERR
# simulate background process
sleep 15 & 
echo ${!} > pidfile.pid
wait
) &
disown

# remove background process by hand
# kill -TERM ${!}
0 голосов
/ 20 марта 2011

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

Если вы все еще хотите, чтобы в вашем скрипте оболочки было отправлено какое-то уведомление, и trap SIGUSR2, например:

#!/bin/sh

BACKGROUND_PROCESS=xterm         # for my testing, replace with what you have

sh -c "$BACKGROUND_PROCESS; rm -f the_pid_file; kill -USR2 $$" &

trap "echo $BACKGROUND_PROCESS ended" USR2

while sleep 1
do
    echo -n .
done
0 голосов
/ 07 марта 2011

Добавьте это в начало вашего скрипта Bash.

#!/bin/bash
trap 'rm "$pidfile"; exit' EXIT SIGQUIT SIGINT SIGSTOP SIGTERM ERR
pidfile=$(tempfile -p foo -s $$)
echo $$ > "$pidfile"
# from here, do your long running process
...