Nota:
-
wait $subshell
não funcionará, pois$subshell
não é filho do processo em que você está executandowait
in. De qualquer forma, você não está esperando o processo fazer owait
, por isso não importa muito. -
kill $subshell
vai matar o subshell, mas nãosleep
se o subshell tiver conseguido iniciá-lo no tempo em quekill
foi executado. No entanto, você pode executarsleep
no mesmo processo comexec
- você pode usar o SIGPIPE em vez do SIGTERM para evitar a mensagem
- deixar uma variável sem aspas nos contextos de lista tem um significado muito especial em
bash
.
Então, tendo dito tudo isso, você pode fazer:
(
subshell=$BASHPID
kill -s PIPE "$subshell" &
sleep 600
)
echo subshell done
(substitua sleep 60
por exec sleep 60
se você quiser que o kill
mate sleep
e não apenas o subshell, que neste caso pode nem ter tempo de executar sleep
no momento em que você o mata ).
De qualquer forma, não tenho certeza do que você quer alcançar com isso.
sleep 600 &
seria uma maneira mais confiável de iniciar sleep
em segundo plano se era isso que você queria fazer (ou (sleep 600 &)
se quisesse ocultar esse processo sleep
do shell principal)
Agora com o seu real
sudo stdbuf -o0 wpa_supplicant -Dwext -i"$wifi" -c/etc/wpa_supplicant/wpa_supplicant.conf
comando, observe que sudo
gera um processo filho para executar o comando (somente porque pode ser necessário registrar seu status ou executar algumas tarefas de sessão do PAM posteriormente). No entanto, stdbuf
executará wpa_supplicant
no mesmo processo, então, no final, você terá três processos (além do restante do script) na ascendência de wpa_supplicant
:
- o subshell
- sudo como filho de 1
- wpa_supplicant (que estava executando stdbuf anteriormente) como filho de 2
Se você matar 1, isso não mata automaticamente 2. Se você matar 2, no entanto, a menos que seja com um sinal como SIGKILL que não pode ser interceptado, isso matará 3, pois sudo
acontece para encaminhar os sinais recebe o comando que ele executa.
De qualquer forma, essa não é a subcala que você gostaria de matar aqui, é 3 ou pelo menos 2.
Agora, se ele estiver sendo executado como root
e o restante do script não for, você não poderá eliminá-lo tão facilmente.
Você precisaria que o kill
fosse feito como root
, então seria necessário:
sudo WIFI="$wifi" bash -c '
(echo "$BASHPID" &&
exec stdbuf -o0 wpa_supplicant -Dwext -i"$WIFI" -c/etc/wpa_supplicant/wpa_supplicant.conf 2>&1
) | {
read pid &&
grep -m1 "pre-shared key may be incorrect" &&
kill -s PIPE "$pid"
}'
Dessa forma, wpa_supplicant
estará sendo executado no mesmo processo $BASHPID
do subshell que estamos fazendo com exec
.
Recebemos o pid através do pipe e executamos kill
como root.
Observe que, se você estiver pronto para esperar um pouco mais,
sudo stdbuf -o0 wpa_supplicant -Dwext -i"$wifi" -c/etc/wpa_supplicant/wpa_supplicant.conf 2>&1 |
grep -m1 "pre-shared key may be incorrect"
Teria wpa_supplicant
morto automaticamente com um SIGPIPE (pelo sistema, então não há problema de permissão) o da próxima vez ele grava algo naquele pipe depois que grep
se foi.
Algumas implementações do shell não esperariam por sudo
depois que grep
retornou (deixando em execução em segundo plano até obter SIGPIPEd) e com bash
, você também pode fazer isso usando a sintaxe grep ... <(sudo ...)
, bash
não aguarda sudo
depois de grep
ter retornado.
Mais em Grep lento para sair depois de encontrar correspondência?