Ao desenvolver código bash multi-threaded, gerenciar processos de servidor ou criar controles de processo, um dos principais desafios geralmente é terminar corretamente, processos bash existentes eficientes e precisos. Esta postagem mostrará como.
Que e um Procedimento Bash?
Um procedimento bash é simplesmente um executável que está rodando. Como um exemplo, quando você inicia a calculadora em seu ambiente de trabalho, um procedimento bash é criado. Tal bash tem dois identificadores de procedimento principais, a saber, a PID e ele PPID, a Identificador de procedimento, e ele Identificador de procedimento principal.
Em resumo, a PID contém um ID único com base em um número para um determinado aplicativo em execução (Em outras palavras, Um procedimento), Entretanto ele PPID para qualquer aplicativo em execução (Em outras palavras, processo) armazena o PID pai do procedimento que iniciou este novo aplicativo, daí o termo 'Pai'.
Além disso, você pode ver imediatamente como isso forma uma estrutura semelhante a uma árvore, tecendo todos os processos até a raiz / primeiro procedimento que tem um PPID a partir de 0.
Para uma postagem relacionada que fornece informações adicionais e um exemplo prático de PID e PPID, É possível que você queira revisar nossa postagem Exportando variáveis no Bash: porquê e como.
A administração do procedimento Bash parece fácil à primeira vista (apenas corra ps -ef
na linha de comando do seu terminal para ver todos os processos em execução no seu sistema, com o prefixo PID e PPID identificadores.
Até terminar um procedimento parece fácil, mas logo avisos e armadilhas começam a aparecer ao lidar com sistemas de gerenciamento de processos mais complexos.
Encerrar um procedimento Bash
Vamos começar simples, iniciando o gnome-calculator
na linha de comando e, em seguida, finalizando o procedimento.
gnome-calculator &
ps -ef | grep gnome-calculator
kill -9 $RELEVANT_PID
nós começamos gnome-calculator
em modo de fundo (usando &
no final do comando), para que possamos ter nosso prompt de terminal de volta imediatamente, sem ter que iniciar outra sessão de terminal.
A seguir, nós usamos ps -ef
em combinação com um tubo|
) e ele grep
comando para localizar o ID do procedimento (PID) da nossa calculadora. A seguir, nós terminamos com um sinal 9 kill
comando. Substituir $RELEVANT_PID
no código com o PID relatado por ps
se você tentar este código.
Observe que o procedimento em segundo plano termina imediatamente kill -9
instrução. Apesar disto, o prompt de comando bash retorna tão rápido que retorna antes mesmo que o planejador de processo possa relatar que o procedimento em segundo plano foi concluído.
E só o fará quando a notificação estiver de acordo com o trabalho existente, Em outras palavras, é mais baseado na extração do que na inserção. Quando pressionamos enter, o sistema verifica e nos notifica que o primeiro procedimento de background foi concluído, ou melhor, estava acabado / removido; [1]+ Killed gnome-calculator
.
Voltando ao nosso kill command
, Um sinal 9 kill
é uma das mortes mais destrutivas que existem. Simplesmente, termine o show na hora, sem ser gentil com isso. Você pode revisar a seção ‘Sinal de numeração para sinais padrão’ alcançável de man signal.7
comando executado no prompt de comando do seu terminal para obter uma lista de todos os tokens disponíveis e seus números correspondentes.
Para os fins desta postagem, usaremos sinal 9 sempre encerrar imediatamente e efetivamente um procedimento. Apesar disto, mesmo ao usar um sinal 9 matar / termine o procedimento, às vezes, um procedimento pode ficar em um morto Estado.
Isso não acontece com frequência no trabalho geral de DevOps, e se isso acontecer, geralmente significa que houve alguns problemas sérios no código do programa (o procedimento que está sendo executado) para iniciar, ou com hardware de sistema ou sistema operacional.
Evite erros e escolha seus próprios processos
Recomeçar com o procedimento anterior, Existe uma maneira de automatizar o PID seleção para que não precisemos digitar manualmente, e então podemos usá-lo a partir de um script? Com certeza há;
gnome-calculator &
ps -ef | grep 'gnome-calculator' | grep -v 'grep' | awk '{imprimir $2}'
ps -ef | grep 'gnome-calculator' | grep -v 'grep' | awk '{imprimir $2}' | xargs matam -9
Aqui começamos de novo nosso gnome-calculator
em modo de fundo, e usado novamente ps
e grep
para encontrar nosso procedimento. É aí que termina a semelhança. Na próxima instrução dentro do conjunto de tubos Bash (passando informações do comando anterior para o próximo usando um símbolo de barra vertical: |
) nós excluímos o grep
procedimento em si (ainda listado como parte do ps
saída, uma vez que é executado durante o nosso script e, por isso, é auto-coletado pelo grep
), usando o -v
opção a grep
e excluindo a palavra 'grep'
.
Para terminar, nós imprimimos o PID (ID de procedimento) de qualquer procedimento descoberto usando awk
e imprimindo o segundo ($2
) coluna de saída apenas. Nós vemos que apenas um PID É devolvido, o que coincide com o fato de que só temos um gnome-calculator
iniciado.
Nosso comando final adiciona um xargs
comando com um kill -9
instrução para terminar nosso (s) processo (s). O xargs funciona de maneira semelhante ao próprio tubo, mas é mais capaz de manipular informações de entrada e passá-las corretamente, permitindo certos programas como kill
(que você não consegue entender nativamente quando é simples PIDeles são enviados para você) aceitar entradas diretas, ou melhor, opções, como o ID do procedimento que é transmitido aqui. Observe que xargs é prefixado com uma barra vertical.
Nossa inclusão de um grep -v 'grep'
evite não só o erro do eventual kill
comando não consegue encontrar o PID associado ao original grep
comando (desde então acabou, tendo cumprido seu dever de grepping para o 'gnome-calculator'
texto), em segundo lugar, também evita o risco de terminar outro comando / procedimento mais recente que pode ter sido iniciado do original. grep
finalizado, com o mesmo ID de procedimento! Mesmo que a chance de isso acontecer seja pequena, é viável.
Trabalhar essas coisas em nosso comando parece melhor, mas ainda não é perfeito. O que é este servidor com 10 usuários e 10 eles começaram uma calculadora? Supondo que temos privilégios semelhantes para sudo, Queremos mesmo encerrar os processos de calculadora dos outros usuários?? Provavelmente não. Então, podemos dar um passo adiante e definir nosso comando da seguinte maneira:
gnome-calculator &
ps -ef | grep 'gnome-calculator' | grep -v 'grep' | grep "$(Quem sou eu)" | awk '{imprimir $2}'
ps -ef | grep 'gnome-calculator' | grep -v 'grep' | grep "$(Quem sou eu)" | awk '{imprimir $2}' | xargs matam -9
Neste exemplo, inserimos um pequeno comando adicional, a saber grep "$(whoami)"
, que executou uma subcamada ($(...)
) e depois executa whoami
dentro dessa subcamada. a whoami
O comando irá retornar os usuários registrados hoje para o terminal. Bingo! Agora acabamos de terminar nossos próprios processos.
Perfeito? Não, infelizmente, erros ainda são possíveis mesmo com uma linha de comando tão detalhada e precisa. Como um exemplo, se a lista de processos contém localidade ou caracteres estranhos, nosso grep
potencialmente ainda falhar. Talvez a versão mais segura seja algo como:
gnome-calculator & ps -ef | grep -Ei --binary-files = text "^ $(Quem sou eu) [0-9 ]+:.*gnome-calculator $" | grep --binary-files = text -v 'grep' | awk '{imprimir $2}' | grep --binary-files = text -o '[0-9]+' | xargs -I{} matar -9 "{}"
Neste exemplo, nós definimos nosso grep
comando muito mais restritivo com um regex: começo (indicado por ^
) com nome de usuário (usando whoami
em uma subcamada), seguido por um espaço necessário, seguido apenas pelos personagens 0-9
e espaço, pelo menos um ou mais (como indicado +
), seguido por dois pontos obrigatórios (parte do tempo), seguido por qualquer caractere até o nome do nosso programa, que deve ser preenchido até o final da linha (como indicado $
). a grep
usar expressões regulares estendidas (-E
) e não diferencia maiúsculas de minúsculas (-i
opção, ou simplesmente i
quando adicionado ao existente -E
opção)
Também protegemos nosso grep da estranha oportunidade de localidade ou caracteres estranhos usando --binary-files=text
, e escrevemos nossos xargs de uma maneira mais segura, indicando uma string de substituição e citando a string de substituição.
Para terminar, nós inserimos um adicional grep -o
com uma expressão regular que encontra os números 0-9
só. Por isso, mesmo se algum programa tentar trapacear este procedimento matando a linha de comando, seria mais difícil de fazer.
Como uma alternativa interessante para definir uma linha de comando de análise, você também pode dar uma olhada no killall
comando:
gnome-calculator & killall 'gnome-calculator'
Para mais informações sobre este comando, você pode entrar no manual usando man killall
. a killall
O comando também permite que você configure opções como --user
para matar apenas os processos pertencentes ao usuário especificado, etc.
Final
Gerenciar processos de várias maneiras nos permite escrever scripts de watchdog de processos, automatizar o gerenciamento de processos, desenvolver melhor código bash multi-threaded, gerenciar processos melhor e mais. Aproveite suas novas habilidades de bash!!