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 / unix / Perguntas / 676835
Accepted
x-yuri
x-yuri
Asked: 2021-11-10 17:43:44 +0800 CST2021-11-10 17:43:44 +0800 CST 2021-11-10 17:43:44 +0800 CST

Definir uma armadilha para INT não funciona em um subshell

  • 772
$ bash -c "trap \"echo INT\" INT; sleep 3" & pid=$!; sleep 1; kill -INT $pid; wait
[1] 27811
INT
[1]+  Done                    bash -c "trap \"echo INT\" INT; sleep 3"

$ (bash -c "trap \"echo INT\" INT; sleep 3" & pid=$!; sleep 1; kill -INT $pid; wait)

Você pode explicar por que o SIGINTmanipulador não é invocado no segundo caso?

shell subshell
  • 1 1 respostas
  • 240 Views

1 respostas

  • Voted
  1. Best Answer
    x-yuri
    2021-11-16T22:34:47+08:002021-11-16T22:34:47+08:00

    O controle de tarefas refere-se ao protocolo para permitir que um usuário se mova entre vários grupos de processos (ou tarefas) em uma única sessão de login.

    https://www.gnu.org/software/libc/manual/html_node/Job-Control.html

    Geralmente é ativado em shells interativos e desativado em não interativos:

    $ echo $-; sleep 1 & fg
    himBHs
    [1] 84366
    sleep 1
    
    $ bash -c 'echo $-; sleep 1 & fg'
    hBc
    bash: line 1: fg: no job control
    

    Nesse caso... aparentemente o controle de trabalho está desabilitado e $-não pode ser invocado:

    $ (echo $-; sleep 1 & fg)
    himBHs
    bash: fg: no job control
    

    O shell associa um trabalho a cada pipeline.

    https://www.gnu.org/software/bash/manual/html_node/Job-Control-Basics.html

    Ou seja, quando o controle de trabalho está habilitado, cada pipeline é executado em um grupo de processos separado.

    pgid.sh:

    #!/usr/bin/env bash
    ps -o pgid= $$
    
    $ ./pgid.sh >&2 | ./pgid.sh >&2; ./pgid.sh; ./pgid.sh & wait
      93439
      93439
      93443
    [1] 93445
      93445
    [1]+  Done                    ./a.sh
    
    $ (./pgid.sh >&2 | ./pgid.sh >&2; ./pgid.sh; ./pgid.sh & wait)
      93749
      93749
      93749
      93749
    

    Um dos trabalhos é um trabalho de primeiro plano, o resto são de segundo plano.

    Os trabalhos em segundo plano não devem estar vinculados ao shell que os iniciou. Se você sair de um shell, eles continuarão em execução. Como tal, eles não devem ser interrompidos por SIGINT, não por padrão. Quando o controle de tarefas está ativado, isso é realizado automaticamente, pois as tarefas em segundo plano são executadas em grupos de processos separados. Quando o controle de trabalho está desabilitado, bashfaz com que os comandos assíncronos ignorem SIGINTe não permite que eles (se forem bashscripts) o substituam.

    Ou seja, aqui:

    $ bash -c "trap 'echo INT' INT; sleep 3" & pid=$!; sleep 1; kill -INT "$pid"; wait
    

    o trabalho em segundo plano ( bash -c "trap 'echo INT' INT; sleep 3") é executado por um shell interativo, que tem o controle de trabalho ativado. Como resultado, o job em background recebe SIGINT.

    Quando o envolvemos em um shell não interativo sem controle de trabalho:

    $ (bash -c "trap 'echo INT' INT; sleep 3" & pid=$!; sleep 1; kill -INT "$pid"; wait)
    

    bash -c "trap 'echo INT' INT; sleep 3"ignora SIGINTe trap ... INTtambém é ignorado.

    Isso pode ser confirmado desta forma:

    $ bash -c "trap 'echo INT' INT; trap; sleep 3" & pid=$!; sleep 1; kill -INT "$pid"; wait
    [1] 293631
    trap -- 'echo INT' SIGINT
    trap -- '' SIGFPE
    INT
    [1]+  Done                    bash -c "trap 'echo INT' INT; trap; sleep 3"
    
    $ (bash -c "trap 'echo INT' INT; trap; sleep 3" & pid=$!; sleep 1; kill -INT "$pid"; wait)
    trap -- '' SIGINT
    trap -- '' SIGQUIT
    trap -- '' SIGFPE
    
    $ bash -c 'ps -o pid,ignored,comm,args -p $$' & wait
    [1] 345833
        PID          IGNORED COMMAND         COMMAND
     345833 0000000000000000 ps              ps -o pid,ignored,comm,args -p 345833
    [1]+  Done                    bash -c 'ps -o pid,ignored,comm,args -p $$'
    
    $ (bash -c 'ps -o pid,ignored,comm,args -p $$' & wait)
        PID          IGNORED COMMAND         COMMAND
     345629 0000000000000006 ps              ps -o pid,ignored,comm,args -p 345629
    

    Algumas citações relevantes:

    Comandos não integrados iniciados pelo Bash têm manipuladores de sinal definidos para os valores herdados pelo shell de seu pai. Quando o controle de tarefa não está em vigor, os comandos assíncronos ignoram SIGINTeSIGQUIT adicionam esses manipuladores herdados. Os comandos executados como resultado da substituição de comando ignoram os sinais de controle de tarefa gerados pelo teclado SIGTTIN, SIGTTOU, e SIGTSTP.

    https://www.gnu.org/software/bash/manual/html_node/Signals.html

    Sinais ignorados na entrada no shell não podem ser interceptados ou redefinidos.

    https://www.gnu.org/software/bash/manual/html_node/Bourne-Shell-Builtins.html#index-trap

    O controle de tarefas refere-se à capacidade de interromper (suspender) seletivamente a execução de processos e continuar (retomar) sua execução posteriormente. Um usuário normalmente emprega esse recurso por meio de uma interface interativa fornecida em conjunto pelo driver de terminal do kernel do sistema operacional e pelo Bash.

    O shell associa um trabalho a cada pipeline. Ele mantém uma tabela de trabalhos atualmente em execução, que podem ser listados com o jobscomando. Quando o Bash inicia um trabalho de forma assíncrona, ele imprime uma linha parecida com:

    [1] 25647
    

    indicando que este trabalho é o número do trabalho 1e que o ID do processo do último processo no pipeline associado a este trabalho é 25647. Todos os processos em um único pipeline são membros do mesmo trabalho. O Bash usa a abstração do trabalho como base para o controle do trabalho.

    Para facilitar a implementação da interface do usuário para o controle de tarefas, o sistema operacional mantém a noção de um ID de grupo de processo de terminal atual. Os membros deste grupo de processos (processos cujo ID do grupo de processos é igual ao ID do grupo de processos do terminal atual) recebem sinais gerados pelo teclado, como SIGINT. Esses processos são considerados em primeiro plano. Processos em segundo plano são aqueles cujo ID de grupo de processos difere do do terminal; tais processos são imunes a sinais gerados pelo teclado. Somente processos em primeiro plano podem ler ou, se o usuário especificar com stty tostop, escrever no terminal. Os processos em segundo plano que tentam ler (gravar para quando stty tostopestiver em vigor) o terminal recebem um SIGTTIN(SIGTTOU) pelo driver de terminal do kernel, que, a menos que seja capturado, suspende o processo.

    https://www.gnu.org/software/bash/manual/html_node/Job-Control-Basics.html

    • 1

relate perguntas

  • Como funciona este comando? mkfifo /tmp/f; cat /tmp/f | /bin/sh -i 2>&1 | nc -l 1234 > /tmp/f

  • FreeBSD's sh: funções de lista

  • Existe uma maneira de fazer ls mostrar arquivos ocultos apenas para determinados diretórios?

  • o que grep -v grep faz

  • Como salvar um caminho com ~ em uma variável?

Sidebar

Stats

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

    Possível firmware ausente /lib/firmware/i915/* para o módulo i915

    • 3 respostas
  • Marko Smith

    Falha ao buscar o repositório de backports jessie

    • 4 respostas
  • Marko Smith

    Como exportar uma chave privada GPG e uma chave pública para um arquivo

    • 4 respostas
  • Marko Smith

    Como podemos executar um comando armazenado em uma variável?

    • 5 respostas
  • Marko Smith

    Como configurar o systemd-resolved e o systemd-networkd para usar o servidor DNS local para resolver domínios locais e o servidor DNS remoto para domínios remotos?

    • 3 respostas
  • Marko Smith

    apt-get update error no Kali Linux após a atualização do dist [duplicado]

    • 2 respostas
  • Marko Smith

    Como ver as últimas linhas x do log de serviço systemctl

    • 5 respostas
  • Marko Smith

    Nano - pule para o final do arquivo

    • 8 respostas
  • Marko Smith

    erro grub: você precisa carregar o kernel primeiro

    • 4 respostas
  • Marko Smith

    Como baixar o pacote não instalá-lo com o comando apt-get?

    • 7 respostas
  • Martin Hope
    user12345 Falha ao buscar o repositório de backports jessie 2019-03-27 04:39:28 +0800 CST
  • Martin Hope
    Carl Por que a maioria dos exemplos do systemd contém WantedBy=multi-user.target? 2019-03-15 11:49:25 +0800 CST
  • Martin Hope
    rocky Como exportar uma chave privada GPG e uma chave pública para um arquivo 2018-11-16 05:36:15 +0800 CST
  • Martin Hope
    Evan Carroll status systemctl mostra: "Estado: degradado" 2018-06-03 18:48:17 +0800 CST
  • Martin Hope
    Tim Como podemos executar um comando armazenado em uma variável? 2018-05-21 04:46:29 +0800 CST
  • Martin Hope
    Ankur S Por que /dev/null é um arquivo? Por que sua função não é implementada como um programa simples? 2018-04-17 07:28:04 +0800 CST
  • Martin Hope
    user3191334 Como ver as últimas linhas x do log de serviço systemctl 2018-02-07 00:14:16 +0800 CST
  • Martin Hope
    Marko Pacak Nano - pule para o final do arquivo 2018-02-01 01:53:03 +0800 CST
  • Martin Hope
    Kidburla Por que verdadeiro e falso são tão grandes? 2018-01-26 12:14:47 +0800 CST
  • Martin Hope
    Christos Baziotis Substitua a string em um arquivo de texto enorme (70 GB), uma linha 2017-12-30 06:58:33 +0800 CST

Hot tag

linux bash debian shell-script text-processing ubuntu centos shell awk ssh

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