在 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
我的输出带有令人讨厌的闪烁:
您可以使用
tput cup 0 0
将光标向上发送到屏幕的左上角。clear
一次。在 bash 中实现实时解决方案可能很棘手。
您可以使用多种方法在 X 秒内运行一次脚本
watch
。我假设你已经myScript.sh
有空了。将 X 替换为您需要的秒数。watch -n X ./myScript.sh
while sleep X; do ./myScript.sh; done
更新。要模拟手表,您可能希望在两次迭代之间清除屏幕。在脚本内部,它看起来是这样的:
将上述选项之一添加到脚本本身。
我假设闪烁是因为您的命令需要一些时间才能返回它们的值。这是我通常的解决方法:
我们的想法是在最后一刻清除屏幕。
如果您
clear
紧接在 之后sleep
,而不是紧接之前,您将能够更轻松地读取输出:但是,我会在这里删除循环,并使用它
watch
来重复运行脚本。这是单个工具的更灵活组合。你可以在 bash 中完全做到这一点。如果文字还在闪烁,则说明您尚未完全阅读前面的答案。
您必须在回显新值之前
clear
进入屏幕,而不是之后。您可以将所有命令放在 while 循环中,并带有一些睡眠时间。在下面的示例中,我每 2 秒休眠一次。因此 date 命令将每 2 秒执行一次
你是:显示一行,然后执行命令显示下一行。
您需要:执行所有命令(不触摸显示屏)并将结果保存在 4 个变量中,然后一次清除并显示这 4 个结果。
如果我修改您自己的脚本,请尝试:
在这里,在不改变显示的情况下长时间执行 4 个请求,然后显示会非常快速地刷新并同时显示 4 个新值。
这 50 行没有闪烁,因为它使用 tput 分别更新每一行。我在每行之间设置了一个睡眠 0.01 来证明这一点。
使用 arg y 运行脚本会向您展示终端窗口用于定位光标的示例。我在回声中硬编码了我的逃逸。你的可能不一样。为了可移植性,您应该使用 tput 动态生成序列。为了提高性能,您应该预先获取应用程序所需的所有 tput 序列,并将它们存储在 shell 中。此外,一旦您有一次固定文本,只需更改可变部分。
请注意,屏幕位置从 tput args 中的 (0, 0) 开始。此外,屏幕命令中的前导零被解释为八进制,这就是我使用 printf 重新格式化可见行号的原因。更新后将光标移开(例如移动到(0,0))也是礼貌的。
您可以在 bash 中设置一个循环 - 构造是您的命令
while true; do ....; done
所在的位置。....
你需要Ctrl+C来停止它。您需要在循环中进入睡眠状态,否则它只会尖叫并吃掉您所有的 CPU 时间。睡眠秒数是获取当前数据和输出过多之间的折衷方案。
如果您在屏幕上以固定列格式化输出宽度方式(使用 printf 命令),那么将更容易看到变化。
我可能会将所有这些的输出发送到一个文件(“完成”之后的重定向),这样你就可以在闲暇时检查它,甚至可以绘制它或进行统计。您可以在另一个窗口中运行
tail -f
命令,该命令将向您显示添加到文件中的最新数据,以便您也可以看到它发生的情况。date
如果数据之间的间隔很重要,您还可以在循环中放置一个命令来为每一行添加时间戳。如果其中任何一个需要更多的骨头上的肉,请再次发布。
睡眠结束后,回显退格并重新显示一个值。这假设您在一个可以显示转义码、终端的宽度和线条的终端上,但它可以作为一个快速的镜头。示例:在等待某个进程完成时显示 Spinner