"armadilha 'killall $$; rm -f $ pasta2; sair' 18 20 24

1

O que há de errado com esse comando?

$ trap 'killall $$ ; rm -f $folder2;exit ' 18 20 24

Esse comando está em for loop, e enquanto isso for está em execução, se eu pressionar CTRL - Z eu quero que ele pare o processo e exclua todos os arquivos que foram criados (dentro de folder2 ) e folder2 em si.

Mas quando pressiono CTRL - Z no terminal ele pára, mas não consigo fazer mais nada depois, nem mesmo CTRL - C não está funcionando.

    
por alex 21.11.2013 / 16:35

2 respostas

4

O problema é que killall está esperando um padrão que corresponda a um nome de processo em vez de seu PID, enquanto $$ fornece o PID de processo atual. Você deseja usar kill .

Além disso, se você quiser remover um diretório junto com todo o seu conteúdo, precisará da opção -r para rm :

Por fim, qualquer coisa que você fizer depois de matar o processo não entrará em vigor: mova o kill para o final do trap e remova o exit ao mesmo tempo:

trap 'rm -rf "$folder2";kill $$' 18 20 24

Se você quiser interromper o funcionamento do for antes de remover $folder2 , use break :

trap 'break;rm -rf "$folder2";kill $$' 18 20 24
    
por 21.11.2013 / 16:46
2

Pegue o seguinte script como exemplo:

#!/bin/bash

trap 'echo bye; kill $$' SIGTSTP
sleep 30

Digamos que você aperte o controle-Z durante o sono. Isso enviará o SIGTSTP para o grupo de processos, que incluirá sleep e bash. Como explicado na resposta de William Pursell a uma pergunta semelhante no Stack Overflow , o bash não executa o manipulador trap até depois do o comando em execução ( sleep ) é finalizado. No entanto, o sono não terminará: ele foi suspenso, porque ele também recebeu o SIGTSTP. E neste ponto, porque está parado, ele irá ignorar o controle-C (SIGTERM), control- \ (SIGQUIT), etc. Nada menos do que o SIGKILL irá derrubá-lo.

Portanto, o seu trap não será executado (a menos que você vá em frente e mate -9 o sono, ele será executado imediatamente).

Para contornar isso, você precisará fazer com que os processos filhos sejam ignorados ou não sejam entregues SIGTSTP, então resolva matá-los você mesmo. Ou execute-os em segundo plano e wait para eles:

#!/bin/bash

trap 'echo bye; kill $$' SIGTSTP
sleep 30 &
wait

O Control-Z realmente funciona como esperado com esse.

    
por 21.11.2013 / 17:58