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 / 793542
Accepted
Gridzbi Spudvetch
Gridzbi Spudvetch
Asked: 2025-04-10 09:27:48 +0800 CST2025-04-10 09:27:48 +0800 CST 2025-04-10 09:27:48 +0800 CST

Como posso executar instruções if em uma saída de comando sem encerrá-la?

  • 772

Tenho que executar quatro ifinstruções separadas (e suas consequências) em uma saída de comando continuamente enquanto ela é atualizada (fazendo quatro coisas diferentes com base em quatro strings diferentes que podem estar na saída). Aqui estão algumas limitações:

  • Ele deve funcionar com as ÚLTIMAS DUAS linhas, pois o comando que estou usando sempre coloca uma quebra de linha no final.
  • Ele deve ser executado sem nunca encerrar o comando original.
  • Tentei canalizar a saída para um arquivo usando entr, mas não funcionou, pois entr só detecta quando o arquivo está fechado e meu método de canalizar para o arquivo não faz isso? Ou algo assim, eu realmente não entendo.

Minhas opções, eu acho, são as seguintes:

  1. Salve continuamente as duas últimas linhas de saída em uma variável e execute as instruções if em um processo paralelo separado sempre que a variável mudar.
  2. Execute todas as instruções if em série como uma única linha, canalizando a saída padrão do comando original sem modificações por todas elas. (Pesquisas superficiais sugerem que executar uma instrução if diretamente no stdin pode não ser possível.)
  3. Canalize o mesmo stdout diretamente para quatro comandos separados ao mesmo tempo.
  4. Encontre uma maneira de canalizar um comando para um arquivo que feche o arquivo a cada atualização.
  5. Canalize a saída do comando para um arquivo e execute a maior parte do script em Python em vez de Bash.

Se alguém souber um método para fazer qualquer um desses, agradeço muito a ajuda. Observe que estou fora do meu alcance aqui e provavelmente precisarei de mais explicações do que o normal. Obrigado :)

bash
  • 2 2 respostas
  • 88 Views

2 respostas

  • Voted
  1. Best Answer
    Sotto Voce
    2025-04-10T14:35:04+08:002025-04-10T14:35:04+08:00

    Uma abordagem mais simples é escrever um script que tenha a saída padrão do comando canalizada para ele. O script lê linha por linha em um while readloop, e o conteúdo de cada linha é correspondido em uma caseinstrução, em vez de uma série de ifinstruções. Como você deve lidar com a linha vazia no final do grupo de linhas? Depois de lê-la, simplesmente ignore-a e aguarde a próxima linha. Aqui está um exemplo:

    #!/usr/bin/env bash
    
    while read -r input_line
    do
      case "${input_line}" in
          one*) echo "Line starting with one"  ;;
          two*) echo "Line starting with two"  ;;
        three*) echo "Line starting with three" ;;
         four*) echo "Line starting with four" ;;
            "") ;;   # ignore empty lines
             *) ;;   # ignore other lines
      esac
    done
    

    As instruções Case realizam correspondências de strings simples na variável fornecida e executam o comando que corresponde ao primeiro correspondente.

    O tipo de correspondência é semelhante a um glob de arquivo. No exemplo, linhas que começam com "um", "dois", "três" ou "quatro" fazem com que o script execute um comando diferente. O ""corresponde a uma string vazia (o resultado da leitura de uma linha vazia com read), e o *corresponde a qualquer outra coisa ainda não especificada na instrução case.

    Não há nenhuma ação especificada para os casos vazio e desconhecido, então o script não faz nada com eles. O loop retornará ao topo e aguardará a próxima linha passar pelo pipe.

    Isso pode ser simplista demais para a correspondência de linhas que você procura ou para as ações que deseja realizar com as quatro cordas que está detectando. Mas talvez seja um começo.

    Você passaria a saída do comando para este script em um pipeline simples:

    command | this_script.sh
    
    • 5
  2. Sotto Voce
    2025-04-11T12:09:26+08:002025-04-11T12:09:26+08:00

    Ao reler a pergunta, vejo a possibilidade de minha resposta anterior não cobrir bem. Você precisa detectar quatro strings, e minha outra resposta funciona melhor quando uma das strings aparece em uma linha na saída do comando. Mas se duas, três ou todas as quatro pudessem aparecer na mesma linha, e você precisasse executar uma ação para cada string, a caseinstrução pode não funcionar bem.

    Aqui está o mesmo while readloop com if/thentestes:

    while read -r input_line
    do
      # skip empty lines
      [[ -z ${input_line} ]] && continue
    
      [[ ${input_line} == pound*bang ]] && {
        echo "Line starts with pound, and has bang"
      }
    
      if [[ ${input_line} == *foo*bar* ]]
      then
        echo "Line has foo and then bar in it"
        echo "This invokes multiple commands"
      fi
    
      if [[ ${input_line} == *bar*baz* ]]
      then
        echo "Line has bar and then baz in it"
      fi
    
      # or you can put no commands here, to ignore other lines
      echo "this command invoked on every line (except empty)"
    
    done
    

    Meu exemplo usa a sintaxe de teste com colchetes duplos ( [[and ]]) porque acredito que as vantagens superam as desvantagens. Para manter o exemplo simples, os testes usam a correspondência de padrões de string interna do Bash em vez de grepor awk(mas isso é algo que você pode fazer).

    O while readloop lê uma linha cada vez que o script atinge o topo do loop. Não há tempo limite, então, se o comando que está sendo enviado para este script pausar, este script aguarda.

    O primeiro processamento do loop [[ -z ${input_line} ]] && continuetesta se $input_line está vazio e, em caso afirmativo, invoca continue, que ignora o restante do loop e retorna ao início. Ele usa uma sintaxe compacta para acoplar o continuecomando ao teste.

    O próximo teste usa a mesma sintaxe de acoplamento compacto, mas invoca um grupo de comandos entre chaves em vez do comando único do teste anterior.

    Os dois testes a seguir mostram cláusulas muito convencionais if/then, que também podem executar um único comando ou vários comandos, como qualquer outro if/then.

    Com exceção das linhas vazias, cada linha é testada por todos os testes fornecidos, de modo que todos podem detectar sua string específica caso ela apareça na linha. Quando várias strings aparecem na mesma linha, cada uma delas será detectada e a ação correspondente será tomada.

    Por fim, todos os comandos no final do loop serão invocados para cada linha (exceto linhas vazias). Talvez seja apropriado que este loop envie as linhas para um arquivo. Ou, se não houver nenhum comando desse tipo, as outras linhas serão ignoradas.

    • 0

relate perguntas

  • exportar variáveis ​​​​env programaticamente, via stdout do comando [duplicado]

  • Problema estranho ao passar variáveis ​​do arquivo de texto

  • Enquanto a linha lê mantendo os espaços de escape?

  • ordem de substituição de processos `te` e `bash`

  • Execute um script muito lento até que seja bem-sucedido

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