Estou usando Linux (Ubuntu) e Bash.
Eu fiz um programa simples em Go. Um for-loop literalmente infinito que imprime texto a cada 20 segundos.
package main
import (
"fmt"
"time"
)
func main() {
for {
fmt.Println("Hi from program 1")
time.Sleep(time.Second * 20)
}
}
Primeiro, registro uma armadilha para o SIGCHLD
sinal usando o comando:
trap 'echo "hi you"' SIGCHLD
Em seguida, inicio um programa de forma assíncrona (em segundo plano) com:
./program &
Eu comecei como um trabalho de segundo plano para que o bash possa usar o terminal. Quando eu executo o comando:
kill -SIGSTOP process_id
a armadilha é acionada, e a mensagem "hi you" é exibida como esperado. No entanto, quando eu executo:
kill -SIGCONT process_id
para retomar o processo, o processo continua em execução (imprimindo "Hi from program 1"), mas a mensagem de trap ("hi you") não é exibida. Eu invoco esses kill
comandos de outro terminal.
Encontrei na documentação do bash o seguinte:
Qualquer armadilha em SIGCHLD é executada para cada processo filho que sai.
Eu poderia entender como exclusivo. Em outras palavras, que a SIGCHLD
armadilha é ativada somente quando o processo filho sai. Se for assim, ficaria claro para mim por que meu exemplo não funciona. No entanto, a SIGCHLD
armadilha também é ativada quando o processo filho é suspenso.
Por que isso está acontecendo? Retomar o processo também gera um SIGCHLD
sinal, então por que a armadilha não dispara nesse caso?
Pergunta relacionada .
É o comportamento desejado no Bash, explicado por este comentário no código-fonte:
É difícil dizer qual é o motivo desse comportamento, pois ele foi introduzido em 2001, antes do Bash começar a usar o Git.