Definir máscara de sinal do processo filho no Bash

1

Aqui está o meu problema - estou tentando escrever um pequeno script wrapper que adiciona um argumento de linha de comando quando o Xorg é chamado (não tenho acesso à origem do chamador). Parecia bastante simples, mas o problema é que Eu estou correndo agora é que o chamador está esperando por um sinal de USR1 do Xorg. Na página do manual do XSERVER:

SIGUSR1

This signal is used quite differently from either of the above. When the server starts, it checks to see if it has inherited SIGUSR1 as SIG_IGN instead of the usual SIG_DFL. In this case, the server sends a SIGUSR1 to its parent process after it has set up the various connection schemes. Xdm uses this feature to recognize when connecting to the server is possible.

Eu pensei que poderia simplesmente capturar o sinal e encaminhá-lo:

#!/bin/bash
parent_trap(){
   echo sending USR1 to $PPID &> /tmp/wrapper.log
   kill -USR1 $PPID
}
trap "parent_trap" USR1
Xorg $@ (extra stuff) &
wait

Mas é claro que isso não funciona, pois o próprio script é iniciado pelo chamador ignorando USR1 . Eu acho que o que eu preciso fazer é fazer com que o script pare de ignorar o sinal, mas também de alguma forma inicie o Xorg com USR1 ignorado (para acionar o comportamento da página man.)

Isso é possível no Bash / alguma outra linguagem de script? Por algumas razões, espero evitar uma solução compilada, mas isso não é impensável. Também é possível que eu esteja completamente pensando sobre isso errado e que haja outra maneira de obter USR1 do Xorg para o chamador.

    
por Kevin 14.07.2018 / 00:03

1 resposta

1

Seu novo script

Em vez de tentar fazer algo extravagante com os sinais, por que não fazer isso:

$ cat xorg_wrapper
#!/bin/bash

exec Xorg $@ (extra stuff)

Como funciona

Para ilustrar o que está acontecendo com o acima, aqui está um exemplo mais elaborado que ajuda a mostrar a mecânica do exec no script acima.

$ cat xorg.bash
#!/bin/bash

echo "script's PID: $$"
sleep 5
echo "starting fakeXorg..."
exec sleep 5

# Nothing below here will execute due to exec
echo $!
echo "fakeXorg finished..."
sleep 5

Isso iniciará o Xorg como você especificou, mas porque estamos usando o exec command Xorg irá assumir o mesmo PID e substituir o nosso script xorg.bash por ele mesmo.

OBSERVAÇÃO: A intenção das três últimas linhas acima é demonstrar que xorg.bash não está mais em execução / em execução após a execução do comando exec sleep ... .

Exemplo

Primeiro, executamos nosso script:

$ ./xorg.bash
script's PID: 22471

...5 seconds passes...

starting fakeXorg...

...now the exec runs and 5 more seconds pass...

$

Se fôssemos monitorar isso em outro shell usando ps auxf , veríamos isso.

fase 1 - xorg.bash pré-exec
$ ps auxf
....
root     21184  0.0  0.3 116596  3412 pts/2    S    20:19   0:00                  \_ /bin/bash
root     22471  0.0  0.1 113176  1400 pts/2    S+   20:43   0:00                      \_ /bin/bash ./xorg.bash
root     22472  0.0  0.0 107948   348 pts/2    S+   20:43   0:00                          \_ sleep 5
fase 2 - xorg.bash post-exec
$ ps auxf
....
root     21184  0.0  0.3 116596  3412 pts/2    S    20:19   0:00                  \_ /bin/bash
root     22471  0.0  0.0 107948   352 pts/2    S+   20:43   0:00                      \_ sleep 5

Observe na fase 1 que xorg.bash tem um PID de 22471, mas na fase 2, o exec sleep 5 agora tem o mesmo PID, 22471.

As linhas depois de exec ...

A função do comando exec faz com que o shell atual seja substituído por outro executável:

   $ help exec
    ...
        Replace the shell with the given command.

Como conseqüência, qualquer comando no xorg.bash nunca é executado porque no ponto em que exec .... é, xorg.bash deixa de existir como um processo, tendo sido substituído pelo comando sleep .

Referências

por 14.07.2018 / 02:52