As interrupções de software em sistemas Linux e Unix são feitas por meio de sinais. Existem muitos sinais diferentes do Linux, mas alguns estão destacados e é essencial entendê-los e conhecê-los: SIGINT, SIGTERM y SIGKILL. É assim que eles funcionam.
Que e um Sinal Linux?
Todos nós entendemos que uma luz vermelha significa que temos que parar de andar ou dirigir. Equivalentemente, em sistemas Linux e Unix, um sinal pode ser passado para um programa ou serviço em execução para interagir com ele. Como um exemplo, pode-se enviar um sinal de luz vermelha para um programa simplesmente transmitindo um SIGTERM
sinal.
Assim como com uma luz vermelha, as pessoas podem optar por continuar caminhando ou dirigindo quando o sinal estiver vermelho. Embora possa não ser uma ideia segura para todos os envolvidos, uma SIGTERM
sinalizar um procedimento fará exatamente isso; o procedimento / o programa pode escolher ignorar o referido sinal.
Todos os sinais básicos do Linux têm um número (1-30 +). Depois de um tempo, um usuário Linux geralmente proficiente conhecerá um ou mais desses. Como um exemplo, a SIGTERM
o sinal corresponde ao número 15 e o sinal 9 (SIGKILL
) é provavelmente o mais conhecido, uma vez que torna possível encerrar à força um procedimento, ao contrário do nosso SIGTERM
exemplo de luz vermelha.
Aqui vemos a tela principal do htop
(você pode instalar este útil utilitário digitando sudo apt install htop
no Ubuntu / hortelã, o sudo yum install htop
em RedHat / Centos / Fedora) com uma série de sinais de terminação e outros (mais abaixo na lista; existem 37 no total) que pode ser enviado para um procedimento previamente selecionado à direita. Pode-se escolher um procedimento pressionando o cursor para cima / para baixo e, em seguida, envie um sinal usando F9.
SIGKILL & SIGTERM
Embora o nome possa soar um pouco sinistro, o jargão Linux comum para a rescisão do processo é que um “arbusto” Um procedimento. Em termos gerais, queremos apenas terminar um procedimento com um -9
(SIGKILL
) sinalizar se o referido procedimento / programa está bloqueado. Lembre-se de que sempre que falamos sobre procedimento ou programa, palavras podem ser trocadas à vontade. Simplesmente, um procedimento é qualquer programa (ou serviço) corrida que recebeu um PID (um identificador de procedimento).
Vejamos um exemplo de como encerrar um procedimento em execução em segundo plano por meio de um SIGKILL
sinalizar para o procedimento em execução. tenha em conta que, como explicado SIGKILL
é bastante destrutivo e encerrará o procedimento, independentemente do que o procedimento deseja fazer com o sinal. O procedimento pode capturar e redirecionar vários sinais, enquanto outros não.
Aqui começamos um sleep 1800
no fundo (usando &
no final do comando), que começou como o primeiro ([1]
) procedimento de fundo com PID 574660
. Subseqüentemente, matamos esse procedimento de segundo plano usando kill -9 574660
, onde ele -9
Representa SIGKILL
.
Embora o procedimento termine imediatamente, não vemos a mensagem de conclusão (procedimento de fundo 1
assassinado, Em outras palavras, [1]+ Killed
) quando o prompt de comando retorna antes que a mensagem seja exibida, Em outras palavras, retornar a linha de comando foi uma operação mais rápida do que a conclusão do procedimento ou equivalente.
Nós verificamos a lista de processos por grepping para o PID ps -ef | grep 574660
. Embora possa haver alguma saída, a saída mostrada é apenas para nossa execução grep
comando; a sleep
O procedimento já terminou.
Vamos avaliar o mesmo com SIGTERM
, Em outras palavras kill -15 ${PID}
Onde ${PID}
é o procedimento que queremos terminar.
Tivemos que pressionar Enter para ativar / mostrar mensagem de conclusão (como explicado anteriormente). Podemos ver que o programa terminou corretamente novamente. Apesar disto, desta vez, embora invisível para este exemplo particular (continue lendo!), Internamente dentro do sleep
código do programa, as coisas eram um pouco diferentes.
Para este caso (usando -15
Em outras palavras SIGTERM
para terminar o procedimento), a sleep
O procedimento foi notificado e teve a possibilidade de tratar o sinal internamente. Subseqüentemente, poderia responder encerrando-se por conta própria, ignorando o sinal ou por meio de qualquer outra ação desenvolvida no código. Além disso, podemos provar que isso é verdade verificando o sinal de saída e / ou a saída:
Aqui começamos o procedimento sleep 2000
duas vezes, e então usou outra sessão shell / terminal para terminar o programa. A primeira vez que usamos kill -9
e a segunda vez que usamos kill -15
para parar o sleep
processo.
Notamos imediatamente como a saída retorna. Killed
em primeiro (kill -9
açao) instância. Pela segunda tentativa (usando kill -15
), nós vemos a saída Terminated
ao invés de; o programa terminou automaticamente. Após os respectivos desligamentos, também verificamos os sinais de saída e descobrimos que os códigos de saída eram diferentes.
Por que isso é importante? Considere programas maiores; nesta circunstância, estávamos terminando um simples sleep
comando. Nenhum dado foi tratado, nenhum tráfego foi enviado para frente e para trás, etc. Mas, E se enviarmos um kill -9
comando para nosso servidor de banco de dados (isto, em geral, exigiria privilégios de nível raiz / sudo)?
Eu acordaria o banco de dados para entrar no modo de recuperação de falha na próxima vez que fosse iniciado porque, tanto quanto o software de banco de dados sabe, tudo o que aconteceu foi “estava lá” seguido de “algum”. Em outras palavras, isso quebrou. Se, em vez disso, tivéssemos emitido um kill -15
, o software de banco de dados pode ter executado um desligamento controlado, como um exemplo, primeiro bloqueando a conexão de novos usuários, então desconectando / encerrar usuários existentes, depois de terminar de escrever os dados, etc. antes de encerrar automaticamente.
Envio de sinais do Linux com sequências de teclado
Você sabia que toda vez que você enviou um CTRL+c
sequência de teclas para um programa em execução, como um exemplo em um terminal, que em vez de um SIGINT
é enviado? Vamos voltar à nossa confiança sleep
comande e tente isso:
Aqui começamos sleep
de novo, e, em seguida, pressione a combinação do teclado CTRL+c
. O programa terminou, o melhor foi interrompida por ele SIGINT
sinal que foi enviado. Solicitamos o código de saída e confirmamos que mais uma vez o código de saída é diferente dos sinais anteriores.
Observe que este código de saída, para dormir, sempre corresponderá ao sinal enviado, mesmo que nem todos os sinais possam ser cobertos. Em outras palavras, ao usar CTRL+c
na linha de comando, o código de saída sempre será 130
, 137
quando morto com kill -9
, e 143
quando kill -15
utilizou-se.
Você pode testar os códigos de saída do comando consultando o $?
variável, que contém o código de saída do comando acima (contanto que um novo comando não tenha iniciado). Conheça o código de saída de um determinado comando em uma situação particular, e / ou como consequência de um determinado sinal enviado para esse comando, ajuda na criação de scripts de soluções que lidam com outros processos, etc. (que é o caso de muitos scripts de shell, especialmente ao gerenciar servidores ou ambientes automatizados).
Outra sequência de teclado frequentemente usada é CTRL+z
. Isso enviará um SIGTSTP
sinal, uma suspend
sinal que imediatamente coloca um procedimento em espera até (como um exemplo) uma 'fg'
O comando é emitido para o mesmo procedimento que o trará de volta ao primeiro plano.
Para obter mais informações sobre gestão de processos, consulte os Hacks de Término do Processo Bash.
Final
Neste post, discutimos os sinais mais importantes do Linux e como podemos usá-los na prática em um ambiente Linux ou Unix. Conhecer as dicas básicas do Linux ajuda no uso diário e no gerenciamento do Linux, como um exemplo, quando um procedimento trava e deve ser encerrado com kill -9
. Em uma postagem futura, podemos considerar a captura de um sinal usando o trap
comando de dentro de um script bash, o que permite estabelecer um procedimento customizado que será executado quando o referido sinal for emitido.
Se você gostou de ler este post, dê uma olhada em nossa série de automação bash começando na automação bash & Scripting Basics. No terceiro post dessa série, também analisamos a administração de processos em segundo plano, que foi mencionado anteriormente nesta postagem.