AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / unix / 问题 / 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

显示从命令更改实时值的 Bash 脚本

  • 772

在 Linux 机器上,我有一系列提供不同传感器状态数值的命令。

这些命令的调用类似于以下内容:

$ command1
5647
$ command2
76
$ command3
8754

这些值是实时变化的,每次我想检查其中一个的状态时,我都必须重新启动命令……这对我没有任何好处,因为我需要双手来操作硬件。

我的目标是制作一个简单的 Bash 脚本来调用这些命令并保持值更新(实时异步或每 x 秒刷新一次值),如下所示:

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

其中x、y和是变化的值z。v

Bash 可以简单有效地实现这一点吗?还是我应该选择用另一种语言来做,比如 Python?

更新更多信息:

我当前的脚本是:

#!/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)

npe是一个返回数值的示例命令。我期望这样的输出:

在此处输入图像描述

我使用命令得到的这个输出watch -n x ./myScript.sh,其中x是秒的刷新值。如果我像这样编辑我的脚本:

#!/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

我的输出带有令人讨厌的闪烁:

在此处输入图像描述

linux
  • 10 10 个回答
  • 8236 Views

10 个回答

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

    您可以使用tput cup 0 0将光标向上发送到屏幕的左上角。clear一次。

    #!/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

    在 bash 中实现实时解决方案可能很棘手。

    您可以使用多种方法在 X 秒内运行一次脚本watch。我假设你已经myScript.sh有空了。将 X 替换为您需要的秒数。

    1. watch -n X ./myScript.sh

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

      更新。要模拟手表,您可能希望在两次迭代之间清除屏幕。在脚本内部,它看起来是这样的:

      while sleep X; do 
         clear; 
         command1;
         command2;
      done
      
    3. 将上述选项之一添加到脚本本身。

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

    我假设闪烁是因为您的命令需要一些时间才能返回它们的值。这是我通常的解决方法:

    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
    

    我们的想法是在最后一刻清除屏幕。

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

    如果您clear紧接在 之后sleep,而不是紧接之前,您将能够更轻松地读取输出:

    #!/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
    

    但是,我会在这里删除循环,并使用它watch来重复运行脚本。这是单个工具的更灵活组合。

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

    你可以在 bash 中完全做到这一点。如果文字还在闪烁,则说明您尚未完全阅读前面的答案。

    您必须在回显新值之前clear进入屏幕,而不是之后。

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

    您可以将所有命令放在 while 循环中,并带有一些睡眠时间。在下面的示例中,我每 2 秒休眠一次。因此 date 命令将每 2 秒执行一次

    #!/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

    你是:显示一行,然后执行命令显示下一行。

    您需要:执行所有命令(不触摸显示屏)并将结果保存在 4 个变量中,然后一次清除并显示这 4 个结果。

    如果我修改您自己的脚本,请尝试:

    #!/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
    

    在这里,在不改变显示的情况下长时间执行 4 个请求,然后显示会非常快速地刷新并同时显示 4 个新值。

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

    这 50 行没有闪烁,因为它使用 tput 分别更新每一行。我在每行之间设置了一个睡眠 0.01 来证明这一点。

    使用 arg y 运行脚本会向您展示终端窗口用于定位光标的示例。我在回声中硬编码了我的逃逸。你的可能不一样。为了可移植性,您应该使用 tput 动态生成序列。为了提高性能,您应该预先获取应用程序所需的所有 tput 序列,并将它们存储在 shell 中。此外,一旦您有一次固定文本,只需更改可变部分。

    请注意,屏幕位置从 tput args 中的 (0, 0) 开始。此外,屏幕命令中的前导零被解释为八进制,这就是我使用 printf 重新格式化可见行号的原因。更新后将光标移开(例如移动到(0,0))也是礼貌的。

    #! /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

    您可以在 bash 中设置一个循环 - 构造是您的命令while true; do ....; done所在的位置。....你需要Ctrl+C来停止它。

    您需要在循环中进入睡眠状态,否则它只会尖叫并吃掉您所有的 CPU 时间。睡眠秒数是获取当前数据和输出过多之间的折衷方案。

    如果您在屏幕上以固定列格式化输出宽度方式(使用 printf 命令),那么将更容易看到变化。

    我可能会将所有这些的输出发送到一个文件(“完成”之后的重定向),这样你就可以在闲暇时检查它,甚至可以绘制它或进行统计。您可以在另一个窗口中运行tail -f命令,该命令将向您显示添加到文件中的最新数据,以便您也可以看到它发生的情况。

    date如果数据之间的间隔很重要,您还可以在循环中放置一个命令来为每一行添加时间戳。

    如果其中任何一个需要更多的骨头上的肉,请再次发布。

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

    睡眠结束后,回显退格并重新显示一个值。这假设您在一个可以显示转义码、终端的宽度和线条的终端上,但它可以作为一个快速的镜头。示例:在等待某个进程完成时显示 Spinner

    • 1

相关问题

  • 有没有办法让 ls 只显示某些目录的隐藏文件?

  • 使用键盘快捷键启动/停止 systemd 服务 [关闭]

  • 需要一些系统调用

  • astyle 不会更改源文件格式

  • 通过标签将根文件系统传递给linux内核

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    模块 i915 可能缺少固件 /lib/firmware/i915/*

    • 3 个回答
  • Marko Smith

    无法获取 jessie backports 存储库

    • 4 个回答
  • Marko Smith

    如何将 GPG 私钥和公钥导出到文件

    • 4 个回答
  • Marko Smith

    我们如何运行存储在变量中的命令?

    • 5 个回答
  • Marko Smith

    如何配置 systemd-resolved 和 systemd-networkd 以使用本地 DNS 服务器来解析本地域和远程 DNS 服务器来解析远程域?

    • 3 个回答
  • Marko Smith

    dist-upgrade 后 Kali Linux 中的 apt-get update 错误 [重复]

    • 2 个回答
  • Marko Smith

    如何从 systemctl 服务日志中查看最新的 x 行

    • 5 个回答
  • Marko Smith

    Nano - 跳转到文件末尾

    • 8 个回答
  • Marko Smith

    grub 错误:你需要先加载内核

    • 4 个回答
  • Marko Smith

    如何下载软件包而不是使用 apt-get 命令安装它?

    • 7 个回答
  • Martin Hope
    user12345 无法获取 jessie backports 存储库 2019-03-27 04:39:28 +0800 CST
  • Martin Hope
    Carl 为什么大多数 systemd 示例都包含 WantedBy=multi-user.target? 2019-03-15 11:49:25 +0800 CST
  • Martin Hope
    rocky 如何将 GPG 私钥和公钥导出到文件 2018-11-16 05:36:15 +0800 CST
  • Martin Hope
    Evan Carroll systemctl 状态显示:“状态:降级” 2018-06-03 18:48:17 +0800 CST
  • Martin Hope
    Tim 我们如何运行存储在变量中的命令? 2018-05-21 04:46:29 +0800 CST
  • Martin Hope
    Ankur S 为什么 /dev/null 是一个文件?为什么它的功能不作为一个简单的程序来实现? 2018-04-17 07:28:04 +0800 CST
  • Martin Hope
    user3191334 如何从 systemctl 服务日志中查看最新的 x 行 2018-02-07 00:14:16 +0800 CST
  • Martin Hope
    Marko Pacak Nano - 跳转到文件末尾 2018-02-01 01:53:03 +0800 CST
  • Martin Hope
    Kidburla 为什么真假这么大? 2018-01-26 12:14:47 +0800 CST
  • Martin Hope
    Christos Baziotis 在一个巨大的(70GB)、一行、文本文件中替换字符串 2017-12-30 06:58:33 +0800 CST

热门标签

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

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve