继续运行命令,直到输出与 Bash 中上次运行的输出不同

继续运行命令,直到输出与 Bash 中上次运行的输出不同

我有一个脚本,希望每 x 秒运行一次,直到输出发生变化。使用简单的 while 或 Until 循环,我知道如何使用 grep 检查特定字符串的输出,但我想要做的是继续迭代循环,直到当前迭代的输出不等于上一次迭代的输出。

我怎样才能在 bash 中实现这一点?

我得到最接近的结果如下,其中命令在每次迭代中运行两次,但这会产生额外的运行,因为 while 循环无法记住上一次迭代的输出。

while [ "$(command)" = "$(command)" ]; do sleep 10m; done

答案1

man 1 watch

-g--chgexit
当输出命令变化。

watchPOSIX 并不要求它,但它很常见。在 Debian 或 Ubuntu 中,它procpskillps(以及一些其他工具)一起包含在软件包中。

例子:

watch -g -n 5 'date +%H:%M'

答案2

这应该可以解决问题-内联解释:

#!/usr/bin/env bash

# Exit if any errors occur or any undefined variables are dereferenced
set -o errexit -o nounset

# Store the outputs in a separate directory
output_directory="$(mktemp --directory)"
last_output_file="${output_directory}/last"
current_output_file="${output_directory}/current"
touch "$current_output_file"
ln --symbolic "$current_output_file" "$last_output_file"
# The count is just here to show that we always run at least twice, and that
# after that we run the command a random number of times.
count=0

while true
do
    echo "$((++count))"

    # This is our command; it prints 0 or 1 randomly
    if [[ "$RANDOM" -gt 16383 ]]
    then
        echo 0 > "$current_output_file"
    else
        echo 1 > "$current_output_file"
    fi

    # Abort the loop when the files differ
    if ! diff --brief "$last_output_file" "$current_output_file"
    then
        break
    fi

    # Shunt the current output to the last
    mv "$current_output_file" "$last_output_file"
done

可能有更简单的方法可以做到这一点,但它具有几个有用的功能:

  • 它避免创建任何多余的文件,例如用于mktemp每个输出的文件。
  • 通过以最后一个输出文件作为当前输出文件的符号链接开始,我们保证第一个diff命令会看到两个相同的文件。这避免了重复执行我们正在测试的命令,但需要额外diff执行一次。

答案3

显然,watch这是要走的路,正如另一个答案。但是如果你确实想要或者需要在 shell 中执行此操作,这里有一种方法可以做到:

#!/bin/sh
unset prev
while output=$(some_command);
      [ "${prev+set}" != set ] || [ "$output" = "$prev" ];
do
    prev=$output
    sleep 10;
done

"${prev+set}"set如果prev在开始时取消设置后设置为某个值,则扩展为,因此实际上它会强制循环的内容至少运行一次。或者,我们可以初始化prev为,但prev=$(some_command)代价是some_command在循环开始时额外运行一次。

此外,正如注释中所述,命令替换会从命令输出中删除所有尾随换行符,因此如果结果中唯一的变化就是这些换行符,则无法区分输出。不过,这应该很少会造成影响。

相关内容