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 / 552125
Accepted
balon
balon
Asked: 2019-11-15 01:19:29 +0800 CST2019-11-15 01:19:29 +0800 CST 2019-11-15 01:19:29 +0800 CST

Script Bash que mostra a alteração dos valores em tempo real dos comandos

  • 772

Em uma máquina Linux tenho uma série de comandos que oferecem valores numéricos do estado de diferentes sensores.

A chamada desses comandos é algo semelhante ao seguinte:

$ command1
5647
$ command2
76
$ command3
8754

Esses valores mudam em tempo real, e toda vez que quero verificar o status de um deles, tenho que reiniciar o comando... Isso não me faz bem, pois preciso das duas mãos para manipular o hardware.

Meu objetivo é fazer um Bash Script simples que chame esses comandos e mantenha o valor atualizado (em tempo real de forma assíncrona ou atualizando o valor a cada x segundos) assim:

$ ./myScript.sh
command1: x
command2: y
command3: z
command4: v

Onde x, y, ze vsão os valores variáveis.

Bash permite isso de forma simples e eficiente? ou devo optar por fazê-lo em outra linguagem, como Python?

ATUALIZAÇÃO com mais informações:

Meu script atual é:

#!/bin/bash
echo "Célula calibrada: " $(npe ?AI1)
echo "Anemómetro: " $(npe ?AI2)
echo "Célula temperatura: " $(npe ?AI3)
echo "Célula temperatura: " $(npe ?AI4)

npesendo um comando de exemplo que retorna o valor numérico. Espero uma saída como esta:

insira a descrição da imagem aqui

Essa saída eu recebo com o comando watch -n x ./myScript.sh, onde xé o valor de atualização de segundos. Se eu editar meu script assim:

#!/bin/bash
while sleep 1; do
   clear; # added to keep the information in the same line 
   echo "Célula calibrada: " $(npe ?AI1);
   echo "Anemómetro: " $(npe ?AI2);
   echo "Célula temperatura: " $(npe ?AI3);
   echo "Célula temperatura: " $(npe ?AI4);
done

Eu recebo minha saída com uma cintilação irritante:

insira a descrição da imagem aqui

linux
  • 10 10 respostas
  • 8236 Views

10 respostas

  • Voted
  1. glenn jackman
    2019-11-15T07:47:57+08:002019-11-15T07:47:57+08:00

    Você pode usar tput cup 0 0para enviar o cursor para o canto superior esquerdo da tela. clearuma vez.

    #!/bin/bash
    clear
    while sleep 1; do
        tput cup 0 0
        printf "%21s %6d    \n" \
          "Célula calibrada: "   $(npe ?AI1) \
          "Anemómetro: "         $(npe ?AI2) \
          "Célula temperatura: " $(npe ?AI3) \
          "Célula temperatura: " $(npe ?AI4)
    done
    
    • 15
  2. Best Answer
    rush
    2019-11-15T01:30:47+08:002019-11-15T01:30:47+08:00

    Pode ser complicado implementar uma solução em tempo real no bash.

    Há muitas maneiras de executar o script uma vez em X segundos que você pode usar watch. Imagino que você já tenha myScript.shdisponível. Substitua X pelo número de segundos que você precisa.

    1. watch -n X ./myScript.sh

    2. while sleep X; do ./myScript.sh; done

      atualizado para emular o relógio, você pode limpar a tela entre as iterações. dentro do script ficará assim:

      while sleep X; do 
         clear; 
         command1;
         command2;
      done
      
    3. adicione uma das opções acima ao próprio script.

    • 13
  3. bxm
    2019-11-15T14:49:15+08:002019-11-15T14:49:15+08:00

    Estou assumindo que a cintilação é porque seus comandos demoram um momento para retornar seus valores. Esta é a minha solução habitual:

    cmds(){
      echo "Célula calibrada: " $(npe ?AI1);
      echo "Anemómetro: " $(npe ?AI2);
      echo "Célula temperatura: " $(npe ?AI3);
      echo "Célula temperatura: " $(npe ?AI4);
    }
    
    while true; do
      out="$(cmds)"
      clear
      echo "$out"
      sleep 1
    done
    

    A ideia é limparmos a tela no último momento possível.

    • 10
  4. Toby Speight
    2019-11-15T03:35:32+08:002019-11-15T03:35:32+08:00

    Se você clearimediatamente após o sleep, em vez de imediatamente antes, poderá ler a saída com mais facilidade:

    #!/bin/sh
    while sleep 1
    do
       clear
       echo "Célula calibrada: " $(npe ?AI1)
       echo "Anemómetro: " $(npe ?AI2)
       echo "Célula temperatura: " $(npe ?AI3)
       echo "Célula temperatura: " $(npe ?AI4)
    done
    

    No entanto, eu removeria o loop aqui e usaria watchpara executar o script repetidamente. Essa é uma composição mais flexível de ferramentas individuais.

    • 5
  5. Paul_Pedant
    2019-11-15T04:08:45+08:002019-11-15T04:08:45+08:00

    Você pode fazer isso exatamente no bash. Se o texto ainda estiver piscando, você não leu as respostas anteriores completamente.

    Você precisa ir para cleara tela antes de ecoar os novos valores, não depois.

    • 3
  6. Kamaraj
    2019-11-15T01:30:28+08:002019-11-15T01:30:28+08:00

    você pode colocar todos os seus comandos dentro do loop while com algum tempo de sono. No exemplo abaixo, coloco sleep a cada 2 segundos. Portanto, o comando date será executado a cada 2 segundos

    #!/bin/bash
    
    while (true)
    do
            echo "Date & Time : $(date)"
            sleep 2
    done
    
    • 2
  7. Olivier Dulac
    2019-11-16T06:09:20+08:002019-11-16T06:09:20+08:00

    Você está: exibindo uma linha e executando o comando para exibir a próxima.

    Você precisa: executar todos os comandos (sem tocar na tela) e salvar os resultados em 4 vars, depois limpar e exibir esses 4 resultados de uma só vez.

    Se eu modificar seu próprio script, tente:

    #!/bin/bash
    while sleep 1; do
        # facultative?#  tput cup 0 0
        ccab="$(npe ?AI1)"
        cane="$(npe ?AI2)"
        ctemp="$(npe ?AI3)"
        ctemp2="$(npe ?AI4)"
        clear
        printf "%21s %6d    \n" \
          "Célula calibrada: "   "$ccab" \
          "Anemómetro: "         "$cane" \
          "Célula temperatura: " "$temp" \
          "Célula temperatura: " "$temp2"
    done
    

    Aqui, a longa execução das 4 solicitações ocorre sem alterar a exibição, então a exibição é atualizada muito rapidamente e exibida de uma só vez com os 4 novos valores.

    • 2
  8. Paul_Pedant
    2019-11-16T07:51:14+08:002019-11-16T07:51:14+08:00

    Isso faz 50 linhas sem piscar, porque usa tput para atualizar cada linha separadamente. Eu coloquei um sono 0,01 entre cada linha para provar isso.

    A execução do script com arg y mostra exemplos do que sua janela de terminal usa para posicionar o cursor. Eu codifiquei minhas fugas no eco. O seu pode ser diferente. Para portabilidade, você deve usar tput para gerar as sequências dinamicamente. Para desempenho, você deve obter todas as sequências de tput que precisará para seu aplicativo antecipadamente e armazená-las no shell. Além disso, uma vez que você tenha o texto fixo no lugar uma vez, apenas altere as partes variáveis.

    Observe que as posições da tela começam em (0, 0) em tput args. Além disso, os zeros à esquerda nos comandos de tela são interpretados como octais, e é por isso que reformato o número da linha visível com printf. Também é educado mover o cursor para fora do caminho (como (0,0)) após a atualização.

    #! /bin/bash
    
    #.. See what a CUrsor Position is on the current terminal.
    [[ "${1}" == y ]] && {
        for r in {0..19}; do
            tput cup ${r} 15 | od -An -t ax1
        done
        exit
    }
    
    tput clear
    
    while sleep 1; do
        for k in {1..50}; do
            sleep 0.01
            RW=$( printf '%.2d' ${k} )
            TS=$(date "+%Y-%m-%d %H:%M:%S.%N")
            echo -n -e "\e[${k};1H${RW}  ${TS}"
        done
        echo -n -e "\e[52;1H"
    done
    
    • 2
  9. Paul_Pedant
    2019-11-15T01:38:46+08:002019-11-15T01:38:46+08:00

    Você pode configurar um loop no bash -- a construção é while true; do ....; doneonde ....estão seus comandos. Você precisaria Ctrl+ Cpara pará-lo.

    Você precisa colocar um sono no loop, ou ele simplesmente gritará e consumirá todo o seu tempo de CPU. Os segundos para dormir são um compromisso entre obter os números atuais e ter muita saída.

    Se você formatar a saída na largura da tela em colunas fixas (use o comando printf), será mais fácil ver as variações.

    Eu provavelmente enviaria a saída de tudo isso para um arquivo (redirecionamento após o "feito"), para que você possa examiná-lo à vontade depois, talvez até grafá-lo ou fazer estatísticas. Você pode executar um tail -fcomando em outra janela, que mostrará os dados mais recentes sendo adicionados ao arquivo para que você possa vê-los também.

    Você também pode colocar um datecomando no loop para marcar cada linha, caso os intervalos entre os dados sejam importantes.

    Poste novamente se algum deles precisar de mais carne nos ossos.

    • 1
  10. Matthias Š
    2019-11-16T00:23:20+08:002019-11-16T00:23:20+08:00

    Após a expiração do sono, ecoe um backspace e reexiba um valor. Isso pressupõe que você esteja em um terminal que pode exibir códigos de escape, a largura e as linhas do terminal, mas funciona como um tiro rápido. Exemplo: Exibir Spinner enquanto aguarda a conclusão de algum processo

    • 1

relate perguntas

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

  • Inicie/pare o serviço systemd usando o atalho de teclado [fechado]

  • Necessidade de algumas chamadas de sistema

  • astyle não altera a formatação do arquivo de origem

  • Passe o sistema de arquivos raiz por rótulo para o kernel do Linux

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