Em um ponto, você estava perto do que parece querer.
a.sh
#!/bin/sh
echo "a.sh running"
sleep 10s
(sleep 10s; pkill -f b.sh) &
bash b.sh
sleep 10s
pkill -f b.sh
echo "a.sh still running"
b.sh
(igual à sua versão)
echo "b is now running"
sleep 1000s
echo "Bananas"
A linha (sleep 10s; pkill -f b.sh) &
em a.sh
cria um subshell que dorme por dez segundos e depois mata b.sh
.
Em seguida, coloca essa subcama no fundo
então a.sh
pode continuar em execução.
a.sh
, em seguida, executa b.sh
, que executa sleep 1000s
.
Dez segundos depois, o sleep 10s
no subshell termina,
e ele (o subshell) executa pkill -f b.sh
, matando o processo b.sh
.
a.sh
, em seguida, continua em execução.
O segundo pkill -f b.sh
não faz nada,
já que o processo b.sh
já foi finalizado.
Isso é o que acontece quando é executado:
$ ./a.sh a.sh running # immediately b is now running # about 10 seconds after the above ./a.sh: line 6: 13684 Terminated bash b.sh # about 10 seconds after the above a.sh still running # about 10 seconds after the above $ # immediately after the above
Isso tem a vantagem de que a.sh
pode voltar a ser executado imediatamente
se b.sh
terminar rapidamente.
Somente se b.sh
for executado por mais de 10 segundos, o pkill
será acionado.
Na outra resposta, a.sh
tem que ficar ocioso
enquanto o sleep
antes do pkill
ocupar o tempo,
mesmo que b.sh
já tenha terminado.
Outro usuário postado um comentário (agora excluído) dizendo
I get
./a.sh a.sh running b is now running Terminated
not what you report. Any idea?
Foi uma noite escura e tempestuosa. De repente, um tiro soou!
- Era um escuro e Noite tempestuosa, Snoopy por Charles M. Schulz
O argumento para pgrep
e pkill
é uma expressão regular;
especificamente, uma expressão regular estendida 1 .
Tente executar cat
e cut
simultaneamente 2 .
Então, faça pgrep c.t
- ele listará dois PIDs,
e você pode confirmar com ps
que eles são cat
e cut
.
Se você tivesse feito exatamente o que eu disse, você realmente deveria ter obtido os mesmos resultados que eu fiz. Mas estou disposto a apostar 42 Zorkmids que você fez algo diferente. Você também:
- Começou
a.sh
com#!/bin/bash
como uma she-bang (primeira linha) em vez de#!/bin/sh
ou - Ran
a.sh
combash a.sh
em vez de./a.sh
.
De repente, um tiro soou!
b.sh
é uma expressão regular que corresponde a b
seguido por qualquer caractere seguido por sh
.
Corresponde a si mesmo ( b.sh
),
e também coisas como b!sh
, b~sh
, b&sh
, b7sh
e bush
.
E…… (espere)…… também corresponde a bash
!
Então pkill -f b.sh
mata todos os processos bash,
e também qualquer outro que tenha b.sh
em seus nomes.
Quando eu corri o que eu corri, meu shell de login
(que é pelo menos parcialmente imune a pkill
) foi bash,
mas a.sh
estava sendo executado com /bin/sh
(mas b.sh
estava sendo executado em bash
).
O comando pkill -f b.sh
eliminou o processo bash b.sh
porque continha ambos bash
e b.sh
.
Mas o /bin/sh
que estava executando a.sh
não foi afetado.
Assumindo que você o executou da maneira que acredito que você o executou
(uma das duas alternativas),
todos os processos de script estavam executando bash
.
E assim, o comando pkill -f b.sh
matou todos os processos de script.
Alterar pkill -f b.sh
para pkill -f 'b\.sh'
(escapando do ponto para que ele corresponda apenas a um ponto, e não a qualquer caractere),
e você deve obter os resultados corretos.