Hacks de rescisão do processo Bash

Ao desenvolver código Bash multithread, gerenciar processos de servidor ou criar watchdogs de processos, um dos principais desafios geralmente é encerrar processos Bash existentes de maneira correta, eficiente e precisa. Este artigo mostrará como.
O que é um processo Bash?
Um processo Bash é simplesmente um executável em execução. Por exemplo, quando você inicia a calculadora em seu ambiente de área de trabalho, um processo Bash é criado. Tal bash tem dois identificadores de processo principais, a saber, o PID e o PPID, o identificador do processo e o identificador do processo pai.
Em resumo, o PID contém um ID exclusivo baseado em número para um determinado aplicativo em execução (ou seja, processo), enquanto o PPID para qualquer aplicativo em execução (ou seja, processo) armazena o PID Pai do processo que iniciou este novo aplicativo, portanto o termo & # 8216; Pai ’.
Você também pode ver imediatamente como isso forma uma estrutura em forma de árvore, interligando todos os processos até a raiz / primeiro processo que tem um PPID de 0.

Para ver um artigo relacionado que fornece informações adicionais e um exemplo prático de PID e PPID, você pode querer revisar nosso Exportando variáveis no Bash: o artigo Por que e como.
O gerenciamento do processo Bash parece fácil à primeira vista (basta executar ps -ef na linha de comando do terminal para ver todos os processos em execução no sistema, prefixados por seus identificadores PID e PPID.
Até mesmo encerrar um processo parece fácil, mas logo as advertências e pegadinhas começam a aparecer quando você lida com sistemas de gerenciamento de processos mais complexos.
Encerrando um processo Bash
Vamos começar de forma simples, iniciando o gnome-calculator na linha de comando e, posteriormente, encerrando o processo.
calculadora e gnome ps -ef | grep gnome-calculator kill -9 $ RELEVANT_PID
Iniciamos o gnome-calculator no modo de segundo plano (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.
Em seguida, usamos ps -ef em combinação com um pipe (|) e o comando grep para localizar o ID do processo (PID) de nossa calculadora. Em seguida, terminamos com um comando signal 9 kill. Substitua $ RELEVANT_PID no código pelo PID relatado por ps se você tentar este código.
Observe que o processo em segundo plano é encerrado imediatamente pela instrução kill -9. No entanto, o prompt de comando do Bash retorna tão rapidamente que volta antes mesmo que o planejador do processo possa relatar que o processo em segundo plano foi encerrado.
E isso só acontecerá quando a notificação estiver alinhada com o trabalho existente, ou seja, for mais baseada em pull do que em push. Quando pressionamos enter, o sistema verifica e nos notifica que o primeiro processo em segundo plano terminou, ou melhor, foi encerrado / eliminado; [1] + Calculadora-gnomo morto.
Voltando ao nosso comando kill, um signal 9 kill é uma das mortes mais destrutivas que existe. Basicamente, encerra o programa no local, sem ser gentil com isso. Você pode revisar a seção & # 8216; Numeração de sinal para sinais padrão &’ seção acessível a partir do comando man signal.7 executado no prompt de comando do seu terminal para uma lista de todos os sinais disponíveis e seus números correspondentes.
Para os fins deste artigo, usaremos o sinal 9 para sempre encerrar um processo imediata e efetivamente. No entanto, mesmo ao usar um sinal 9 de eliminação / término do processo, às vezes um processo pode permanecer em um estado extinto.
Isso não acontece com frequência no trabalho geral de DevOps e, se acontecer, geralmente significa que houve alguns problemas sérios no código do programa (o processo sendo executado) para começar, ou com o hardware do sistema ou sistema operacional .
Como evitar erros & Selecionando apenas processos de propriedade
Começando novamente com o processo acima, existe uma maneira de automatizar a seleção do PID para que não precisemos digitar manualmente e possamos usá-lo dentro de um script? Com certeza;
calculadora e gnome ps -ef | grep 'gnome-calculator' | grep -v 'grep' | awk '' ps -ef | grep 'gnome-calculator' | grep -v 'grep' | awk '' | xargs kill -9

Aqui nós começamos novamente nossa calculadora gnome no modo de segundo plano e novamente usamos ps e grep para encontrar nosso processo. É aí que termina a semelhança. Na próxima instrução dentro do conjunto de canais Bash (passando informações do comando anterior para o próximo usando um símbolo de barra vertical: |) excluímos o próprio processo grep (também listado como parte da saída do ps, pois está em execução durante nosso sequência de comandos e, portanto, é auto-captado pelo grep), usando a opção -v para o grep e excluindo a palavra 'grep'.
Finalmente, imprimimos o PID (ID do processo) de qualquer processo descoberto usando awk e imprimindo apenas a segunda coluna ($ 2) da saída. Vemos que apenas um único PID é retornado, o que corresponde ao fato de termos apenas uma única calculadora gnome iniciada.
Nosso comando final adiciona um comando xargs com uma instrução kill -9 para encerrar nosso (s) processo (s). O xargs funciona de forma semelhante a um pipe em si, mas é mais capaz de lidar com várias informações de entrada e passá-las corretamente, permitindo que certos programas como kill (que não pode entender nativamente quando PIDs simples estão sendo enviados para ele) para aceitar entrada direta, ou melhor, opções – como o processo de ID &’ sendo transmitido aqui. Observe que xargs é prefixado por uma barra vertical.
Nossa inclusão de um grep -v 'grep' evita não apenas o erro do eventual comando kill não ser capaz de encontrar o PID associado ao comando grep original (já que ele foi encerrado desde então, tendo-o cumprido &’ s dever de grep para o texto 'gnome-calculator'), também evita o risco de encerrar outro comando / processo mais recente que pode ter sido iniciado desde que o grep original foi encerrado, com o mesmo ID de processo! Embora a possibilidade de isso ocorrer é pequena, é possível.
Colocar essas coisas em nosso comando parece melhor, mas ainda não é perfeito. O que é este é um servidor com 10 usuários e todos os 10 iniciaram uma calculadora? Assumindo que temos privilégios do tipo sudo, queremos realmente encerrar os processos de calculadora dos outros usuários? Provavelmente não. Portanto, podemos dar um passo adiante e definir nosso comando da seguinte maneira:
gnome-calculator & ps -ef | grep 'gnome-calculator' | grep -v 'grep' | grep "$ (whoami)" | awk '' ps -ef | grep 'gnome-calculator' | grep -v 'grep' | grep "$ (whoami)" | awk '' | xargs kill -9
Neste exemplo, inserimos um pequeno comando adicional, chamado grep "$ (whoami)", que executou um subshell ($ (...)) e então executa whoami dentro desse subshell. O comando whoami retornará ao terminal os usuários atualmente conectados. Bingo! Agora encerramos apenas nossos próprios processos.
Perfeito? Não, infelizmente, erros ainda são possíveis, mesmo com uma linha de comando sintonizada tão detalhada. Por exemplo, se a lista de processos contém locale ou caracteres estranhos, nosso grep ainda pode falhar. Talvez a versão mais segura seja algo parecido com:
gnome-calculator & ps -ef | grep -Ei --binary-files = text "^ $ (whoami) [0-9] +:. * gnome-calculator $" | grep --binary-files = text -v 'grep' | awk '' | grep --binary-files = text -o '[0-9] \ +' | xargs -I {} kill -9 "{}"

Neste exemplo, definimos nosso comando grep muito mais restritivo com uma expressão regular: start (indicado por ^) com o nome de usuário (usando whoami em um subshell), seguido por um espaço obrigatório, seguido apenas pelos caracteres 0 -9 e espaço, pelo menos um ou mais (conforme indicado por +), seguido por dois pontos obrigatórios (parte do tempo), seguido por qualquer caractere até o nome do nosso programa, que deve preencher até o final da linha ( conforme indicado por $). O grep usa expressões regulares estendidas (-E) e não faz distinção entre maiúsculas e minúsculas (opção -i ou simplesmente i quando adicionado à opção -E existente)
Nós também protegemos nosso grep para a possibilidade ímpar de locale ou caracteres estranhos usando --binary-files = text, e escrevemos nossos xargs de uma maneira mais segura, indicando um string de substituição e citando a string de substituição.
Finalmente, inserimos um grep -o adicional com uma expressão regular que pesquisa apenas os números de 0 a 9. Portanto, mesmo se algum programa tentasse enganar esse processo, eliminando a linha de comando, seria mais difícil fazê-lo.
Como uma alternativa interessante para definir uma linha de comando de análise, você também pode querer dar uma olhada no comando killall:
gnome-calculator & killall 'gnome-calculator'

Para obter mais informações sobre este comando, você pode acessar o manual usando man killall. O comando killall também permite que você defina opções como --user para eliminar apenas os processos que o usuário especificado possui, etc.
Concluindo
Manipular processos de várias maneiras nos permite escrever scripts de watchdog de processos, automatizar o manuseio de processos, desenvolver melhor código bash multi-threaded, gerenciar processos melhor e muito mais. Aproveite suas novas habilidades Bash!
Nenhum comentário