Processos perdem anexo ao shell quando iniciados via bash -x

2

Normalmente, se eu executar emacs & e depois fechar o shell, o emacs sairá.

No entanto, se eu executar bash -x foo.foo (onde foo.foo é um script que executa emacs & ), o emacs permanecerá aberto mesmo quando eu sair do shell.

Existe uma maneira de fechar todos os processos quando o shell é encerrado, mesmo quando os processos foram iniciados por meio de uma chamada para bash -x ?

    
por jhourback 23.12.2013 / 18:52

2 respostas

3

Não, isso não é possível:

Normalmente, quando você inicia um programa em segundo plano usando & , o shell libera o controle sobre ele, e ele não será finalizado quando o shell sair. Isso é verdadeiro mesmo se você não usar a opção -x para bash .

Shells interativos são a exceção a esta regra: eles podem fazer algo chamado “job control” para monitorar os processos-filhos que eles iniciaram e terminá-los quando o shell interativo / login sair. (Isso também é configurável; é possível deixar os processos em segundo plano em execução e esse é, na verdade, o comportamento padrão da maioria dos processos.)

Você pode contornar isso de várias formas, mas apenas para finalizar o emacs quando o script foo.foo sair, não quando o shell que o chama sair - isso ocorre porque chamar bash -x executa outro (sub) shell, e o interativo shell pai não "sabe" sobre os filhos do subshell.

    
por 24.12.2013 / 00:46
0

Você pode adicionar um trap na EXIT que mata todos os processos da sua sessão:

(para adicionar ao seu .bashrc ):

killall_on_exit() {
  sid=$(ps -o sid= -p "$$")
  if [ "$sid" -eq "$$" ]; then
    # we're the session leader
    (
      trap '' TERM
      ps -eo pgid= -o sid= |
        awk -v sid="$sid" '$2 == sid && !seen[$1]++ {print "-" $1}' |
        xargs kill -s TERM --
    )
  fi
}
trap killall_on_exit EXIT

Isso mata todos os grupos de processos em sua sessão. Isso não matará os processos que são iniciados em uma nova sessão, mas como novas sessões são tipicamente iniciadas por emuladores de terminal, se você matar o emulador de terminal, é provável que o processo que ele gerou também morra (e seus filhos se o líder for uma festa interativa com essa mesma armadilha).

nohup ou disown normalmente não tornam os comandos imunes a isso.

Você pode substituir o TERM s acima por HUP s, mas observe que alguns comandos como xterm ignoram os SIGHUPs.

Para imunizar um comando contra o SIGTERM, inicie-o como:

(trap '' TERM; emacs &)
    
por 27.02.2014 / 16:31

Tags