AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / computer / Perguntas / 1458984
Accepted
Pritzl
Pritzl
Asked: 2019-07-13 00:19:48 +0800 CST2019-07-13 00:19:48 +0800 CST 2019-07-13 00:19:48 +0800 CST

Como posso interromper um processo em segundo plano embutido quando meu script é interrompido?

  • 772

Em um script de shell, faço o seguinte:

#!/bin/sh

while true; do ssh -o ExitOnForwardFailure=yes -L 8080:localhost:80 -N server; sleep 1; done &

... rest of the script, which uses the tunnel as made above ...

Isso garante que o túnel seja sempre mantido aberto e, portanto, seja reaberto em caso de perda de conexão. Este túnel é usado em outras partes do script principal, omitido aqui. Essas peças podem lidar com um túnel não funcional, elas simplesmente tentam novamente mais tarde.

Quando o script principal morre, por exemplo devido a um SIGTERMou SIGINT, quero que esse whileloop pare também. Não há necessidade de manter esse túnel aberto depois que o script principal morre.

Qual é a abordagem comum para fazer isso em scripts de shell? Note que eu quero duas coisas:

  1. impedir a reexecução do sshcomando
  2. interrompa e desconecte a sessão atual em andamento ssho mais rápido possível

Não tenho certeza de como fazer tudo isso em scripts de shell.

Observe que atualmente estou trabalhando em plain sh, mas posso prosseguir bashse necessário.

linux bash
  • 1 1 respostas
  • 319 Views

1 respostas

  • Voted
  1. Best Answer
    Kamil Maciorowski
    2019-07-13T01:58:45+08:002019-07-13T01:58:45+08:00

    Uma abordagem um tanto geral.

    while true; do foo; sleep 1; done &
    # the rest of the script here
    kill -- -"$$"
    

    O truque é que o script executa processos filhos (aqui fooentre outros) com ID do grupo de processos (PGID) igual ao PID do shell. Isso se propaga para netos e assim por diante. O próprio shell também está nesse grupo de processos. Existem exceções (trabalhos em shells interativos, timeout) portanto, isso não é tão geral quanto você deseja; ainda assim, com fooum sshcomando simples ou semelhante em um script não interativo, a abordagem deve funcionar.

    killcom um argumento negativo envia sinais para todo o grupo de processos.

    Uma ressalva: uma possível condição de corrida. Em geral, foopode ser eliminado antes que o subshell receba e manipule o sinal. Se o atraso for longo o suficiente (por qualquer motivo), um novo foopode ser gerado (especialmente se sem sleep 1) depois de killfazer seu trabalho. Considere esta melhoria:

    while true; do foo; sleep 1; done &
    subpid=$!
    # the rest of the script here
    kill "$subpid"
    wait "$subpid" 2>/dev/null
    # at this moment we're certain the subshell is no more, new foo will not be spawned
    trap '' TERM
    # foo will maintain the old PGID, so…
    kill -- -"$$" 2>/dev/null
    

    A armadilha está aqui apenas para fazer o shell principal sair normalmente sem imprimir Terminatedno console.


    Não é uma abordagem geral para qualquer processo em segundo plano, mas geralmente é um método útil para sshcenários semelhantes.

    Use autossh. Do seu manual :

    autosshé um programa para iniciar uma cópia sshe monitorá-lo, reiniciando-o conforme necessário caso ele morra ou pare de passar tráfego.

    […]

    autosshprocura distinguir a forma de morte do sshprocesso que está a acompanhar e actuar de forma adequada. As regras são:

    1. Se o sshprocesso saiu normalmente (por exemplo, alguém digitou exitem uma sessão interativa), autosshsai em vez de reiniciar;
    2. Se autosshele próprio receber um SIGTERM, SIGINT, ou um SIGKILLsinal, assume que foi sinalizado deliberadamente e sai após matar o sshprocesso filho;
    3. […]
    4. […]
    5. Se o processo filho sshmorrer por qualquer outro motivo, autosshtentará iniciar um novo.

    Portanto:

    autossh … &
    apid=$!
    # the rest of the script here
    kill "$apid"
    

    Observe que você não será notificado se o túnel não puder ser estabelecido em primeiro lugar. Como essa também é uma possível falha em sua abordagem original, não estou abordando esse problema aqui.

    • 3

relate perguntas

  • Notificar-enviar notificações aparecendo na janela

  • execute o contêiner do docker como root

  • Como ativar o sensor de impressão digital no domínio e no diretório ativo do Linux

  • Como alterar permanentemente Ctrl + C para Ctrl + K no CentOS 7?

  • como abrir um arquivo de escritório do WSL

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    O visualizador de fotos do Windows não pode ser executado porque não há memória suficiente?

    • 5 respostas
  • Marko Smith

    Como faço para ativar o WindowsXP agora que o suporte acabou?

    • 6 respostas
  • Marko Smith

    Área de trabalho remota congelando intermitentemente

    • 7 respostas
  • Marko Smith

    Serviço do Windows 10 chamado AarSvc_70f961. O que é e como posso desativá-lo?

    • 2 respostas
  • Marko Smith

    O que significa ter uma máscara de sub-rede /32?

    • 6 respostas
  • Marko Smith

    Ponteiro do mouse movendo-se nas teclas de seta pressionadas no Windows?

    • 1 respostas
  • Marko Smith

    O VirtualBox falha ao iniciar com VERR_NEM_VM_CREATE_FAILED

    • 8 respostas
  • Marko Smith

    Os aplicativos não aparecem nas configurações de privacidade da câmera e do microfone no MacBook

    • 5 respostas
  • Marko Smith

    ssl.SSLCertVerificationError: falha na verificação do certificado [SSL: CERTIFICATE_VERIFY_FAILED]: não foi possível obter o certificado do emissor local (_ssl.c:1056)

    • 4 respostas
  • Marko Smith

    Como posso saber em qual unidade o Windows está instalado?

    • 6 respostas
  • Martin Hope
    Albin Como faço para ativar o WindowsXP agora que o suporte acabou? 2019-11-18 03:50:17 +0800 CST
  • Martin Hope
    fixer1234 O "HTTPS Everywhere" ainda é relevante? 2019-10-27 18:06:25 +0800 CST
  • Martin Hope
    Kagaratsch O Windows 10 exclui muitos arquivos minúsculos muito lentamente. Algo pode ser feito para agilizar? 2019-09-23 06:05:43 +0800 CST
  • Martin Hope
    andre_ss6 Área de trabalho remota congelando intermitentemente 2019-09-11 12:56:40 +0800 CST
  • Martin Hope
    Riley Carney Por que colocar um ponto após o URL remove as informações de login? 2019-08-06 10:59:24 +0800 CST
  • Martin Hope
    zdimension Ponteiro do mouse movendo-se nas teclas de seta pressionadas no Windows? 2019-08-04 06:39:57 +0800 CST
  • Martin Hope
    Inter Sys Como Ctrl+C e Ctrl+V funcionam? 2019-05-15 02:51:21 +0800 CST
  • Martin Hope
    jonsca Todos os meus complementos do Firefox foram desativados repentinamente, como posso reativá-los? 2019-05-04 17:58:52 +0800 CST
  • Martin Hope
    MCK É possível criar um código QR usando texto? 2019-04-02 06:32:14 +0800 CST
  • Martin Hope
    SoniEx2 Altere o nome da ramificação padrão do git init 2019-04-01 06:16:56 +0800 CST

Hot tag

windows-10 linux windows microsoft-excel networking ubuntu worksheet-function bash command-line hard-drive

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve