Bash: 如何结合 watch 使用 alias 命令

Bash: How to use an alias command in combination with watch

我想将 bash 中的别名命令与 watch 命令结合使用。 watch 命令是多个链式命令。

一个非常简单的例子,我认为它会如何工作(但它没有):

alias foo=some_command          # a more complicated command
watch -n 1 "$(foo) | grep bar"  # foo is not interpreted as the alias :(

watch -n 1 "$(foo) | grep sh" 错误有两个原因。

  1. watch "$(cmdA) | cmdB"被shell执行时,$(cmdA)gets expandedbefore运行 watch。然后 watch 将执行 cmdAoutput 作为命令(在大多数情况下应该会失败)并将其输出管道到 cmdB。你的意思可能是 watch 'cmdA | cmdB'.

  2. 别名 foo 仅在当前 shell 中定义。 watch 不是内置命令,因此必须在另一个不知道别名 foo 的 shell 中执行它的命令。 this answer 中介绍了一个小技巧,但是我们必须进行一些调整以使其与管道和选项一起使用

alias foo=some_command
alias watch='watch -n 1 ' # trailing space treats next word as an alias
watch foo '| grep sh'

请注意,watch 的选项必须在 watch 别名中指定。结尾的 space 导致 只有下一个词 被视为别名。使用 watch -n 1 foo bash 会尝试将 -n 扩展为别名,而不是 foo.

我创建了一个使用 --color 选项的函数,并允许您使用 -n 指定刷新间隔。

swatch_usage() {
    cat <<EOF >&2
NAME
       swatch - execute a program periodically with "watch". Supports aliases.

SYNOPSIS
       swatch [options] command

OPTIONS
       -n, --interval seconds (default: 1)
              Specify update interval.  The command will not allow quicker than 0.1 second interval.
EOF
}

swatch() {
    if [ $# -eq 0 ]; then
        swatch_usage
        return 1
    fi
    seconds=1

    case "" in
    -n)
        seconds=""
        args=${*:3}
        ;;
    -h)
        swatch_usage
        ;;
    *)
        seconds=1
        args=${*:1}
        ;;

    esac

    watch --color -n "$seconds" --exec bash -ic "$args || true"
}

我只需要颜色和时序支持,但我相信您可以根据需要添加更多。

该函数的核心是它在交互模式下直接使用 bash 执行您的命令,因此可以使用通常在 bash.[=15 中可用的任何别名或命令=]

我没有编写脚本的经验,所以公平警告,你的里程可能会有所不同。有时我必须按几次 Ctrl+C 才能让它停止,但不管怎样,我已经经常使用它 6 个月了,没有任何问题。

主旨形式:https://gist.github.com/ablacklama/550420c597f9599cf804d57dd6aad131