Como modificar o comportamento dos scripts em sinais usando armadilhas de bash

Como modificar o comportamento dos scripts em sinais usando armadilhas de bash

Objetivo

O objetivo deste tutorial é descrever como usar a casca de bash armadilha Construído para tornar nossos scripts capazes de executar determinadas ações quando recebem um sinal ou em outras situações específicas.

Requisitos

  • nenhum requesito especial

Dificuldade

FÁCIL

Convenções

  • # - requer que os comandos Linux sejam executados com privilégios de raiz também
    diretamente como usuário root ou por uso de sudo comando
  • $ - Requer que os comandos do Linux sejam executados como um usuário não privilegiado regular

Introdução

Ao escrever scripts destinados a funcionar por um tempo considerável, é muito importante aumentar sua robustez, tornando -os capazes de reagir aos sinais do sistema, executando ações específicas quando alguns deles são recebidos. Podemos realizar esta tarefa usando a festa armadilha construídas em.

O que são armadilhas?

Uma armadilha é um mecanismo de festa que permite personalizar um comportamento de script quando recebe um sinal. Isso é muito útil, por exemplo, para garantir que o sistema esteja sempre em um estado consistente. Imagine que você escreveu um script que durante o tempo de execução precisa criar alguns diretórios: se, por exemplo, um sinal de sigint for enviado, o script será interrompido, deixando para trás os diretórios que criou. Usando armadilhas, podemos lidar com situações como esta.

Sintaxe da armadilha

A sintaxe do Trap é muito simples e fácil de entender: Primeiro, devemos chamar a armadilha construída, seguida pelas ações a serem executadas, então devemos especificar o (s) sinal (s) que queremos reagir:

armadilha [-lp] [[arg] sigspec]

Vamos ver o que é o possível armadilha opções são para.

Quando usado com o -eu Flag, o comando TRAP exibirá apenas uma lista de sinais associados aos seus números. É a mesma saída que você pode obter executando o matar -l comando:

$ trap -l 1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL 5) SIGTRAP 6) SIGABRT 7) SIGBUS 8) SIGFPE 9) SIGKILL 10) SIGUSR1 11) SIGSEGV 12) SIGUSR2 13) ) SIGSTKFLT 17) SIGCHLD 18) SIGCONT 19) SIGSTOP 20) SIGTSTP 21) SIGTTIN 22) SIGTOU 23) SIGURG 24) SIGXCPU 25) Sigxfsz 26) Sigvtalrm 27) SigProf 28) Sigwinch 29) 35) sigrtmin+1 36) sigrtmin+2 37) sigrtmin+3 38) sigrtmin+4 39) sigrtmin+5 40) sigrtmin+6 41) sigrtmin+7 42) sigrtmin+8 43) sigrtmin+9 44) 45) sigrtmin+11 46) sigrtmin+12 47) sigrtmin+13 48) sigrtmin+14 49) sigrtmin+15 50) sigrtmax-14 51) sigrmax-13 52) sigrtmax-12) sigrtmax-11 54) 55) SIGRTMAX-9 56) SIGRTMAX-8 57) SIGRTMAX-7 58) SIGRTMAX-6 59) SIGRTMAX-5 60) SIGRTMAX-4 61) SIGRTMAX-3 62) SIGRTMAX-2 63) 

É realmente importante especificar que é possível reagir apenas a sinais que permitem que o script responda: o Sigkill e Sigstop Os sinais não podem ser capturados, bloqueados ou ignorados.

Além dos sinais, as armadilhas também podem reagir a alguns pseudo-sinal como saída, err ou depuração, mas os veremos em detalhes mais tarde. Por enquanto, lembre -se de que um sinal pode ser especificado por seu número ou por seu nome, mesmo sem o Sig prefixo.

Sobre a -p opção agora. Esta opção tem sentido apenas quando um comando não é fornecido (caso contrário, produzirá um erro). Quando a armadilha é usada com ela, uma lista das armadilhas previamente definidas será exibida. Se o nome ou número do sinal for especificado, apenas a armadilha definida para esse sinal específica será exibida, caso contrário, nenhuma distinção será feita e todas as armadilhas serão exibidas:

$ trap 'echo "sigint pego!"'Sigint

Definimos uma armadilha para capturar o sinal SIGINT: ela apenas exibirá a mensagem "SIGINT capturada" na tela quando o sinal for recebido pelo shell. Se agora usarmos a armadilha com a opção -p, ele exibirá a armadilha que acabamos de definir:

$ trap -p trap -'echo "sigint pego!"'Sigint 

A propósito, a armadilha agora está "ativa"; portanto, se enviarmos um sinal SIGINT, usando o comando Kill, ou com o atalho Ctrl-C, o comando associado na armadilha será executado (^C é apenas impresso porque da combinação de chave):

^CSIGINT PAGADO!

Armadilha em ação

Agora escreveremos um script simples para mostrar armadilha em ação, aqui está:

#!/usr/bin/Env Bash # # Um script simples para demonstrar como a armadilha funciona # set -e Set -U Set -o Pipefail Trap 'echo "Signal capturado, limpando ..."; rm -i linux_tarball.alcatrão.XZ 'SIGINT SIGTERM ECHO "Download de tarball…" wget -o linux_tarball.alcatrão.xz https: // cdn.núcleo.org/pub/linux/kernel/v4.X/Linux-4.13.5.alcatrão.xz &> /dev /null
cópia de

O script acima tenta baixar o mais recente Linux Kernel Tarball no diretório do que ele é lançado usando wget. Durante a tarefa, se os sinais SIGINT ou SIGTERTER forem recebidos (observe como você pode especificar mais de um sinal na mesma linha), o arquivo parcialmente baixado será excluído.

Nesse caso, o comando é na verdade dois: o primeiro é o eco que imprime a mensagem na tela, e a segunda é a real rm Comando (fornecemos a opção -i para ele, para que ele solicite a confirmação do usuário antes de remover) e eles são separados por um semicolon. Em vez de especificar comandos dessa maneira, você também pode chamar funções: isso lhe daria mais reutilização. Observe que, se você não fornecer nenhum comando, o (s) sinal (s) será apenas ignorado!

Esta é a saída do script acima quando recebe um sinal de sigint:

$ ./FetchLinux.Download de tarball… ^CSignal pego, limpando… rm: remova o arquivo regular 'linux_tarball.alcatrão.xz '? 

Uma coisa muito importante a lembrar é que, quando um script é encerrado por um sinal, como acima, seu status de existência será o resultado de 128 + o número do sinal. Como você pode ver, o script acima, sendo encerrado por um sigint, tem um status de saída de 130:

$ echo $? 130 

Por fim, você pode desativar uma armadilha apenas ligando armadilha seguido pelo - sinal, seguido pelo (s) nome (s) ou número (s) de sinal:

armadilha - sigint sigterm

Os sinais retomarão o valor que eles tinham na entrada da concha.

Pseudo-sinal

Como já mencionado acima, a TRAP pode ser definida não apenas para sinais que permitem que o script responda, mas também ao que podemos chamar de "pseudo-sinal". Eles não são tecnicamente sinais, mas correspondem a certas situações que podem ser especificadas:

SAÍDA

Quando SAÍDA é especificado em uma armadilha, o comando da armadilha será executado na saída da concha.

ERRAR

Isso fará com que o argumento da armadilha seja executado quando um comando retornar um status de saída diferente de zero, com algumas exceções (o mesmo da opção de shell errexit): o comando não deve fazer parte de um enquanto ou até laço; não deve fazer parte de um se construir, nem parte de um && ou || lista, e seu valor não deve ser invertido usando o ! operador.

DEPURAR

Isso fará com que o argumento da armadilha seja executado antes de cada comando simples,
para, caso ou Selecione comandos e antes do primeiro comando nas funções do shell.

RETORNAR

O argumento da armadilha é executado após uma função ou um script proveniente de uso fonte ou o . comando.

Tutoriais do Linux relacionados:

  • Como propagar um sinal para os processos filhos de uma festa…
  • Como executar operações de administração com Ansible…
  • Como instalar o sinal no Linux
  • Coisas para instalar no Ubuntu 20.04
  • Como usar o comando killall no linux
  • Como sair do script Bash
  • Coisas para fazer depois de instalar o Ubuntu 20.04 fossa focal linux
  • Comandos Linux: os 20 comandos mais importantes que você precisa para…
  • VirtualBox Aumente o tamanho do disco no Linux
  • Guia de solução de problemas gerais GNU/Linux para iniciantes