Não é possível executar 'kill - - $$' no meu shell script quando eu o sudo

2

Eu tenho um script de shell que inicia alguns processos filho de plano de fundo. Eu quero que eles sempre estejam rodando - a menos que o processo pai saia ou seja morto (então eu tenho os filhos em um loop que apenas sempre reinicia se ele parar).

Este script parece funcionar relativamente bem, se eu o executar diretamente. Mas assim que eu sudo , ele não irá limpar os outros processos corretamente:

#!/bin/bash

trap "trap - SIGTERM && kill -- -$$" SIGINT SIGTERM EXIT

# Start first background thing
while true;
do
        sleep 1
        echo "SOME PROCESS RUNNING IN THE BACKGROUND"
        echo "SHOULD AUTO-RESTART IF IT GETS KILLED OR CRASHES"
        sleep 5
done &

# Start second background thing
while true;
do
        sleep 3
        echo "ANOTHER ONE..."
        sleep 3
done &

# Wait for quit keypress
while true
do
        echo "Press 'Q' to quit"
        read -rsn1
        if [ $REPLY == "q" ] || [ $REPLY == "Q" ]; then
                echo "Are you sure? [Y/N]"
                read -rsn1
                if [ $REPLY == "y" ] || [ $REPLY == "Y" ]; then
                        kill -- -$$
                        exit
                fi
        fi
        echo ""
        sleep 1
done

# Wait
wait

Quando estou sudo'ing, se pressionar CTRL + C ou pressionar "Q" para sair, ele sairá do processo pai (principal), mas não dos filhos, e eu recebo este erro:

adam@TG-BBCAM-01:~ $ sudo ./temp.sh
Press 'Q' to quit
Are you sure? [Y/N]
./temp.sh: line 31: kill: (-29098) - No such process
./temp.sh: line 1: kill: (-29098) - No such process
adam@TG-BBCAM-01:~ $ SOME PROCESS RUNNING IN THE BACKGROUND
SHOULD AUTO-RESTART IF IT GETS KILLED OR CRASHES
ANOTHER ONE...
SOME PROCESS RUNNING IN THE BACKGROUND
SHOULD AUTO-RESTART IF IT GETS KILLED OR CRASHES
ANOTHER ONE...
SOME PROCESS RUNNING IN THE BACKGROUND
SHOULD AUTO-RESTART IF IT GETS KILLED OR CRASHES
ANOTHER ONE...
SOME PROCESS RUNNING IN THE BACKGROUND

Obviamente, porque não matou as crianças, elas ainda estão em execução e inundando meu shell ainda com saída. Quando não sudo, funciona muito bem.

Parece ser o kill -- -$$ no trap e na parte do "keypress monitor" do meu script. Comentar um fora não conserta o outro.

Alguém sabe como posso consertar isso? Eu gostaria que funcionasse na maioria das situações (pelo menos, sudo ou não).

Obrigado!

    
por Adam Plocher 05.09.2017 / 11:38

1 resposta

2

É kill -- -"$pgid" , ou seja, tem que ser um id de grupo grupo . kill -- -"$$" só funcionaria se o shell fosse o líder do grupo de processos, o que não ocorre ao executar com sudo de um shell interativo:

$ sudo bash -c 'ps -j; exit'
  PID  PGID   SID TTY          TIME CMD
26786 26786 29719 pts/39   00:00:00 sudo
26794 26786 29719 pts/39   00:00:00 bash
26795 26786 29719 pts/39   00:00:00 ps

sudo é o líder do grupo de processos, não bash .

Então, você precisa fazer kill -- -"$(ps -o pgid= -p "$$")" ou simplesmente:

kill 0

Qual é o comando para matar seu próprio grupo de processos.

Em qualquer caso, isso é apenas uma coisa válida se seu script for chamado por conta própria a partir de um shell interativo (que executa o controle de tarefas).

Observe também que em:

(the-script; echo "$?")

Ou:

the-script | cmd

A subshell no primeiro caso ou cmd é a segunda também é colocada no mesmo grupo de processos, então seria morta também por esse kill 0 .

    
por 05.09.2017 / 11:46