pkill que aguarda

1

Existe uma ferramenta parecida com um pkill que faz isso:

  1. envia sinal para todos os processos correspondentes
  2. aguarde N segundos até que os processos tenham terminado
  3. se todos os processos tiverem terminado, nice: exit
  4. se alguns processos não tiverem terminado, envie SIGKILL

Para mim, é importante que a ferramenta aguarde até que os processos tenham realmente terminado.

Eu sei que é muito fácil fazer isso na minha linguagem de script favorita, mas neste caso seria muito bom se eu usasse uma ferramenta que já existe.

Isso precisa ser executado no SuSE-Linux e no Ubuntu.

    
por guettli 24.01.2018 / 09:38

3 respostas

8

Não existe um comando "padrão" que forneça o comportamento que você procura. No entanto, no Debian e derivados, você pode usar start-stop-daemon 's --stop ação com a opção --retry :

start-stop-daemon --stop --oknodo --retry 15 -n daemontokill

enviará SIGTERM para todos os processos chamados daemontokill , espere até 15s para que eles parem, envie SIGKILL para todos os processos restantes (da seleção inicial) e aguarde 15 segundos para que eles morram. Ele sairá com o status 0 se não houver nada para matar ou todos os processos forem interrompidos, 2 se alguns processos ainda estiverem por aí após o segundo tempo limite.

Existem várias opções para combinar processos de várias maneiras, consulte a documentação (link acima) para detalhes. Você também pode fornecer uma programação mais detalhada com tempos limites variáveis.

start-stop-daemon faz parte do pacote dpkg , por isso está sempre disponível nos sistemas Debian (e derivados). Algumas distribuições que não são .deb também disponibilizam o pacote; por exemplo, o openSUSE Leap 42 tem isso. É bem fácil construir em outras plataformas:

git clone https://salsa.debian.org/dpkg-team/dpkg.git 
cd dpkg
autoreconf -fi && ./configure && make

Você precisará de autoconf , automake , libtool , gettext . Quando a construção estiver concluída, você encontrará start-stop-daemon no diretório utils .

    
por 24.01.2018 / 10:02
4

Você pode usar o comando timeout com killall -w

por exemplo:

# timeout 3 killall -vws2 $PROCESS_NAME || killall -vws9 $PROCESS_NAME

timeout irá "timeout" após 3 secends e sairá com o código de erro, que então você pega com || e então executa killall -s9 para forçar o kill.

    
por 11.02.2018 / 23:26
2

Você pode criar seu próprio script que atenderá ao seu caso. Após este post uso inútil de kill -9 e fonte reallykill

#!/bin/sh
#
# $Id: reallykill,v 1.2 2004/10/11 09:36:48 jmates Exp $
#
# The author disclaims all copyrights and releases this script into the
# public domain.
#
# Kills the specified processes by starting with the TERM signal and
# only if necessary working up to the violent KILL signal. For more
# information, see:
#
# http://sial.org/howto/shell/kill-9/

if [ -z "$1" ]; then
  echo "usage: 'basename $0' pid [pid ..]" >&2
  exit 100
fi

cycle_kill () {
  PID=$1
  RETVAL=0

  for signal in "TERM" "INT" "HUP" "KILL"; do
    kill -$signal $PID
    RETVAL=$?
    [ $RETVAL -eq 0 ] && break
    echo "warning: kill failed: pid=$PID, signal=$signal" >&2
    sleep 1
  done

  return $RETVAL
}

for pid in "$@"; do
  cycle_kill $pid
done

Você pode simplesmente baixar o script para o seu diretório bin:

 curl http://web.archive.org/web/20080213192428if_/http://sial.org:80/howto/shell/kill-9/reallykill > $HOME/bin/killwait && chmod +x $HOME/bin/killwait

Eu usaria isso dessa maneira:

ping -q localhost &
killwait 'pidof ping'

Talvez você queira alterar a ordem dos sinais com o INT como primeiro, para que você tenha uma saída com um resumo do comando ping. O comando fornecido não espera se o sinal KILL for bem-sucedido, mas deve funcionar, pois o processo será eliminado pelo sistema.

    
por 08.02.2018 / 16:53