Skip to content

  • Entretenimento
  • Animais de estimação
  • alimentação
  • Viagens
  • CONTACTE-NOS
  • SOBRE NÓS
  • Toggle search form

Como usar sinais do Linux em scripts Bash

Posted on August 4, 2022 By admin No Comments on Como usar sinais do Linux em scripts Bash

fatmawati achmad zaenuri/Shutterstock.com

O kernel do Linux envia sinais aos processos sobre quais eventos eles devem reagir. Scripts bem comportados lidam com sinais de maneira elegante e robusta e podem limpar depois de si mesmos, mesmo se você pressionar Ctrl+C. Aqui está como.

Table of Contents

  • Sinais e processos
  • Conheça os sinais
  • Sinais na linha de comando
  • Capturando sinais em scripts
  • Manipulando sinais em scripts
  • Sinais de leitura

Sinais e processos

Sinais são mensagens curtas, rápidas e unidirecionais enviadas para processos como scripts, programas e daemons. Eles informam o processo de algo que aconteceu. O usuário pode ter pressionado Ctrl+C ou o aplicativo pode ter tentado gravar na memória à qual não tem acesso.

Se o autor do processo pretendia que um determinado sinal pudesse ser enviado a ele, ele pode escrever uma rotina no programa ou script para lidar com esse sinal. Essa rotina é chamada de manipulador de sinal. Ele capta ou intercepta o sinal e executa uma ação em resposta a ele.

O Linux usa muitos sinais, como veremos, mas de uma perspectiva de script, há apenas um pequeno subconjunto de sinais nos quais você pode estar interessado. Em particular, em scripts não triviais, os sinais que dizem ao script para parar devem ser interceptados (se possível) e uma parada suave deve ser executada.

Por exemplo, scripts que criam arquivos temporários ou abrem portas de firewall podem ter a opção de excluir arquivos temporários ou fechar portas antes que eles parem. Se o script morrer no momento em que recebe o sinal, seu computador pode ficar em um estado imprevisível.

Veja como lidar com sinais em seus próprios scripts.

Conheça os sinais

Alguns comandos do Linux têm nomes enigmáticos. Este não é o caso do controle que captura os sinais. É chamado trap. Também podemos usar trap com o -l (list) para nos mostrar a lista completa de sinais usados ​​pelo Linux.

trap -l

Listar sinais no Ubuntu com trap -l

Embora nossa lista numerada termine em 64, na verdade existem 62 sinais. Os sinais 32 e 33 estão faltando. Eles não são implementados no Linux. Eles foram substituídos por recursos no gcc compilador para gerenciar threads em tempo real. Tudo do sinal 34, SIGRTMINno sinal 64, SIGRTMAXsão sinais em tempo real.

Você verá diferentes listagens em diferentes sistemas operacionais do tipo Unix. No OpenIndiana, por exemplo, os sinais 32 e 33 estão presentes, juntamente com vários sinais adicionais, elevando o número total para 73.

Listar sinais no OpenIndiana com trap -l

Os sinais podem ser referenciados por nome, número ou pelo nome abreviado. Seu nome curto é simplesmente seu nome com o primeiro “SIG” removido.

Os sinais são emitidos por muitas razões diferentes. Se você pode decifrá-los, seu propósito está contido em seu nome. O impacto de um sinal se enquadra em uma das seguintes categorias:

  • Fim: O processo está completo.
  • Ignorar: O sinal não afeta o processo. Este é apenas um sinal informativo.
  • Coração: Um arquivo dump-core é criado. Isso geralmente acontece porque o processo transgrediu de alguma forma, como uma violação de memória.
  • Pare: O processo é interrompido. Quer dizer, é no intervaloNão completo.
  • Continuar: Diz a um processo parado para continuar em execução.

Estes são os sinais que você encontrará com mais frequência.

  • SIGA: Sinal 1. A conexão com um host remoto, como um servidor SSH, foi encerrada inesperadamente ou o usuário fez logout. Um script que recebe esse sinal pode sair normalmente ou pode optar por tentar se reconectar ao host remoto.
  • SIGINT: Sinal 2. O usuário pressionou Ctrl+C para forçar o encerramento de um processo, ou kill O comando foi usado com o sinal 2. Tecnicamente este é um sinal de interrupção, não um sinal de fim, mas um script interrompido sem um manipulador de sinal geralmente terminará.
  • SIGQUIT: Sinal 3. O usuário pressionou a combinação Ctrl+D para forçar um processo a encerrar, ou o kill comando foi usado com o sinal 3.
  • SIGFPE: Sinal 8. O processo tentou realizar uma operação matemática ilegal (impossível), como divisão por zero.
  • SIGKILL: Sinal 9. Este é o sinal equivalente de uma guilhotina. Você não pode pegá-lo ou ignorá-lo, e isso acontece instantaneamente. O processo termina imediatamente.
  • SIGTERM: Sinal 15. Esta é a versão mais atenciosa do SIGKILL. SIGTERM também diz a um processo para terminar, mas pode ficar preso e o processo pode executar seus processos de limpeza antes de sair. Isso permite uma parada suave. Este é o sinal padrão emitido pelo kill ordenado.

Sinais na linha de comando

Uma maneira de capturar um sinal é usar trap com o número ou nome do sinal e uma resposta que você deseja que aconteça se o sinal for recebido. Podemos demonstrar isso em uma janela de terminal.

Este comando prende o SIGINT sinal. A resposta é imprimir uma linha de texto na janela do terminal. Nós usamos o -e (habilitar escapes) opção com echo para que possamos usar o “\n” especificador de formato.

trap 'echo -e "+c Detected."' SIGINT

Interceptar Ctrl+C na linha de comando

Nossa linha de texto é impressa cada vez que pressionamos a combinação Ctrl+C.

Para ver se uma armadilha está configurada em um sinal, use o -p (armadilha de impressão).

trap -p SIGINT

Verifique se uma armadilha está definida em um sinal

Usando trap sem opções faz a mesma coisa.

Para redefinir o sinal para seu estado normal não interceptado, use um hífen “-” e o nome do sinal capturado.

trap - SIGINT
trap -p SIGINT

Removendo uma armadilha de um sinal

Sem saída de trap -p O comando indica que nenhuma armadilha está configurada neste sinal.

Capturando sinais em scripts

Podemos usar o mesmo formato geral trap comando em um script. Este script captura três sinais diferentes, SIGINT, SIGQUITe SIGTERM.

#!/bin/bash

trap "echo I was SIGINT terminated; exit" SIGINT
trap "echo I was SIGQUIT terminated; exit" SIGQUIT
trap "echo I was SIGTERM terminated; exit" SIGTERM

echo $$
counter=0

while true
do 
  echo "Loop number:" $((++counter))
  sleep 1
done

Os três trap as instruções estão na parte superior do script. Observe que incluímos o exit controle dentro da resposta a cada um dos sinais. Isso significa que o script reage ao sinal e sai.

Copie o texto em seu editor e salve-o em um arquivo chamado “simple-loop.sh”, e torne-o executável usando o chmod ordenado. Você precisará fazer isso para todos os scripts deste artigo se quiser seguir em seu próprio computador. Basta usar o nome de script apropriado em cada caso.

chmod +x simple-loop.sh

Faça um script executável com chmod

O resto do script é muito simples. Precisamos saber o ID do processo do script, então temos o script ecoando para nós. o $$ A variável contém o ID do processo do script.

Criamos uma variável chamada counter e defini-lo para zero.

o while o loop será executado indefinidamente, a menos que seja interrompido com força. Ele incrementa o counter variável, a envia de volta para a tela e adormece por um segundo.

Vamos executar o script e enviar sinais diferentes.

./simple-loop.sh

Um ID de script foi encerrado com Ctrl+C

Quando pressionamos “Ctrl + C”, nossa mensagem é impressa na janela do terminal e o script é finalizado.

Vamos executá-lo novamente e enviar o SIGQUIT relatório usando kill ordenado. Teremos que fazer isso de outra janela do terminal. Você precisará usar o ID do processo informado pelo seu próprio script.

./simple-loop.sh
kill -SIGQUIT 4575

Um ID de script foi encerrado com SIGQUIT

Como esperado, o script sinaliza a chegada do sinal e depois sai. E finalmente, para provar o ponto, vamos fazê-lo novamente com o SIGTERM sinal.

./simple-loop.sh
kill -SIGTERM 4584

Um ID de script foi encerrado com SIGTERM

Verificamos que podemos capturar vários sinais em um script e reagir a cada um de forma independente. A etapa que leva isso de interessante a útil é adicionar manipuladores de sinal.

Manipulando sinais em scripts

Podemos substituir a string de resposta pelo nome de uma função em seu script. o trap O comando então chama essa função quando o sinal é detectado.

Copie este texto em um editor e salve-o em um arquivo chamado “grace.sh”, e torne-o executável com chmod.

#!/bin/bash

trap graceful_shutdown SIGINT SIGQUIT SIGTERM

graceful_shutdown()
{
  echo -e "\nRemoving temporary file:" $temp_file
  rm -rf "$temp_file"
  exit
}

temp_file=$(mktemp -p /tmp tmp.XXXXXXXXXX)
echo "Created temp file:" $temp_file

counter=0

while true
do 
  echo "Loop number:" $((++counter))
  sleep 1
done

O script arma uma armadilha para três sinais diferentes— SIGHUP, SIGINTe SIGTERM– usando um único trap declaração. A resposta é o nome do graceful_shutdown() função. A função é chamada cada vez que um dos três sinais capturados é recebido.

O script cria um arquivo temporário no diretório “/tmp”, usando mktemp. O padrão de nome de arquivo é “tmp.XXXXXXXXXX”, então o nome de arquivo será “tmp”. seguido por dez caracteres alfanuméricos aleatórios. O nome do arquivo ecoa na tela.

O resto do roteiro é igual ao anterior, com um counter variável e infinito while ciclo.

./grace.sh

Um script executando um desligamento normal excluindo um arquivo temporário

Quando o arquivo recebe um sinal que faz com que ele seja fechado, o graceful_shutdown() função é chamada. Isso exclui nosso único arquivo temporário. Em uma situação real, ele poderia fazer toda a limpeza exigida pelo seu script.

Além disso, agrupamos todos os nossos sinais capturados e os processamos com uma única função. Você pode capturar sinais individualmente e enviá-los para suas próprias funções de manuseio dedicadas.

Copie este texto e salve-o em um arquivo chamado “triple.sh”, e torne-o executável usando o chmod ordenado.

#!/bin/bash

trap sigint_handler SIGINT
trap sigusr1_handler SIGUSR1
trap exit_handler EXIT

function sigint_handler() {
  ((++sigint_count))

  echo -e "\nSIGINT received $sigint_count time(s)."

  if [[ "$sigint_count" -eq 3 ]]; then
    echo "Starting close-down."
    loop_flag=1
  fi
}

function sigusr1_handler() {
  echo "SIGUSR1 sent and received $((++sigusr1_count)) time(s)."
}

function exit_handler() { 
  echo "Exit handler: Script is closing down..."
}

echo $$
sigusr1_count=0
sigint_count=0
loop_flag=0

while [[ $loop_flag -eq 0 ]]; do
  kill -SIGUSR1 $$
  sleep 1
done

Definimos três armadilhas na parte superior do script.

  • Uma armadilha SIGINT e tem um manipulador chamado sigint_handler().
  • A segunda captura um sinal chamado SIGUSR1 e usa um manipulador chamado sigusr1_handler() .
  • A armadilha número três prende o EXIT sinal. Este sinal é acionado pelo próprio script quando ele fecha. Definindo um manipulador de sinal para EXIT significa que pode definir uma função que será sempre chamada no final do script (a não ser que seja eliminada com o sinal SIGKILL). Nosso gerente se chama exit_handler() .

SIGUSR1 e SIGUSR2 são sinais fornecidos para que você possa enviar sinais personalizados para seus scripts. Como você interpreta e reage a eles depende inteiramente de você.

Deixando os manipuladores de sinal de lado por enquanto, o corpo do script deve ser familiar para você. Ele retorna o ID do processo para a janela do terminal e cria variáveis. Variável sigusr1_count registra o número de vezes SIGUSR1 foi processado e sigint_count registra o número de vezes SIGINT foi manipulado. o loop_flag a variável é definida como zero.

o while loop não é um loop infinito. Ele irá parar de fazer o loop se o loop_flag variável é definida como qualquer valor diferente de zero. Cada rotação do while loop usa kill para enviar o SIGUSR1 sinal para este script, enviando-o para o ID do processo do script. Scripts podem enviar sinais para si mesmos!

o sigusr1_handler() função incrementa o sigusr1_count variável e envia uma mensagem para a janela do terminal.

Cada vez que o SIGINT sinal é recebido, o siguint_handler() função incrementa o sigint_count variável e retorna seu valor para a janela do terminal.

Se o sigint_count variável é igual a três, a loop_flag A variável é definida como um e uma mensagem é enviada para a janela do terminal informando ao usuário que o processo de desligamento foi iniciado.

Porque loop_flag não é mais igual a zero, o while loop termina e o script é encerrado. Mas esta ação aumenta automaticamente a EXIT sinal e o exit_handler() função é chamada.

./triple.sh

Um script usando SIGUSR1, exigindo três combinações Ctrl+C para fechar e capturar o sinal EXIT no desligamento

Após pressionar Ctrl+C três vezes, o script termina e invoca automaticamente o exit_handler() função.

Sinais de leitura

Ao capturar sinais e processá-los em funções de manipulador simples, você pode fazer com que seus scripts Bash fiquem atrás deles, mesmo que eles saiam inesperadamente. Isso lhe dá um sistema de arquivos mais limpo. Ele também evita instabilidade na próxima vez que o script for executado e, dependendo da finalidade do script, pode até evitar vulnerabilidades de segurança.

RELACIONADO: Como auditar a segurança do seu sistema Linux com Lynis

Tools

Post navigation

Previous Post: Melhores difusores de óleos essenciais para 2022
Next Post: Julgamento por difamação de Alex Jones Sandy Hook: juiz nega pedido de anulação do julgamento, júri delibera

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

Arquivo

  • August 2022
  • July 2022
  • June 2022
  • May 2022

Categorias

  • Entertainment
  • Food
  • Pets
  • Tools
  • Travel

Postagens recentes

  • Projetor Pico de ultra-orçamento Vimgo P10: nada mal por US $ 250
  • Quais ferramentas você precisa para alcançar um DevOps eficaz?
  • Os melhores programas de ficção científica no Prime Video
  • Apple TV Plus: todos os novos programas de TV estão chegando em agosto
  • Missouri, que proíbe o aborto, pega o inseto verde do hidrogênio
  • About Us
  • Contact Us
  • DMCA
  • Privacy Policy
  • Terms and conditions

Copyright © 2022.

Powered by PressBook WordPress theme