OS X Bash,“监视”命令

Posted

技术标签:

【中文标题】OS X Bash,“监视”命令【英文标题】:OS X Bash, 'watch' command 【发布时间】:2012-03-23 08:44:22 【问题描述】:

我正在寻找在 Mac OS X 上复制 Linux 'watch' 命令的最佳方法。我想每隔几秒运行一个命令,以使用 'tail' 和输出文件的内容进行模式匹配'sed'。

在 Mac 上我最好的选择是什么?可以在不下载软件的情况下完成吗?

【问题讨论】:

因为我必须配置办公室中使用我的脚本的所有 Mac brew 的手表似乎没有接收到我的路径或别名上的命令。 除了命令之外,您还可以使用应用程序 /Applications/Utilities/Console.app 来监视日志文件。它允许使用基本搜索进行过滤 这不属于apple.stackexchange.com吗? 你可以使用像brew这样的包管理器。 【参考方案1】:

安装了Homebrew:

brew install watch

【讨论】:

如果你在 mac 上使用 brew 绝对是正确的选择。 更多细节将不胜感激。当我搜索“brew watch osx”时,这是最高搜索结果。 编辑:显然这是一个 Linux 命令。对于那些不确定如何使用watch的人: ***.com/questions/13593771/… 这个来自 brew 的 watch 似乎没有读取用户别名。在执行watch somealias 时,我得到一个找不到命令。 @NickMc 使用 watch 的正确方法是在使用 watch somealias 时执行 watch [command] 假设 somealias 是可以在终端中运行的命令。 鉴于已接受答案的简单性,在我看来,您的答案是 1. 过分杀伤力 2. 隐藏细节实现,让其他人认为 watch 命令非常难以实现。 【参考方案2】:

您可以使用 shell 循环模拟基本功能:

while :; do clear; your_command; sleep 2; done

这将永远循环,清除屏幕,运行您的命令,然后等待两秒钟 - 基本的 watch your_command 实现。

您可以更进一步,创建一个可以接受your_commandsleep_duration 作为参数的watch.sh 脚本:

#!/bin/bash
# usage: watch.sh <your_command> <sleep_duration>

while :; 
  do 
  clear
  date
  $1
  sleep $2
done

【讨论】:

我相信手表只显示第一屏输出。如果您想做类似的事情,请将your_command 更改为your_command 2&gt;&amp;1|head -10 这很好用,但我更喜欢sleep $2:-1 使间隔可选。 另外,它的echo "$(date)" 等同于date? 它也不适用于管道。这是一个有各种改进的分叉:daniel.lubarov.com/simple-watch-script-for-osx 当输出超过一屏时不像watch那样工作。仅显示结尾,而watch 仅显示顶部。 (都不理想)【参考方案3】:

使用MacPorts:

$ sudo port install watch

【讨论】:

没有比直接使用watch 命令更好的方法了。 为什么使用 brew 而不是 MacPorts? @bmauter,每个人都有自己的:***.com/questions/21374366/… @CenterOrbit,这正是我问的原因。 @joseph.hainline 说不要使用 MacPorts,但没有说明原因。 watch 命令在 MacPorts 中被破坏了吗? 我从来没有从使用 MacPorts 中恢复过来。它最终彻底搞砸了我的系统,以至于我不得不完全重新格式化我的硬盘驱动器。一路自制——我挑战你找到一些流行的东西,这些东西在 HB 上没有的端口上。【参考方案4】:

上面的 shell 可以解决问题,您甚至可以将它们转换为别名(您可能需要包装一个函数来处理参数):

alias myWatch='_()  while :; do clear; $2; sleep $1; done ; _'

例子:

myWatch 1 ls ## Self-explanatory
myWatch 5 "ls -lF $HOME" ## Every 5 seconds, list out home directory; double-quotes around command to keep its arguments together

或者,Homebrew 可以从http://procps.sourceforge.net/ 安装手表:

brew install watch

【讨论】:

如果你将别名包装在一个函数中,为什么你更喜欢函数? 没有故意的偏好;我只是有创建别名的习惯。这些习惯可能源于不依赖或不支持功能的遗留 shell,但我无法确认。【参考方案5】:

可能“看”不是你想要的。您可能想寻求帮助以解决您的问题,而不是实施您的解决方案! :)

如果您的真正目标是根据从tail 命令看到的内容触发操作,那么您可以将其作为尾部本身的一部分来执行。您可以按需运行代码,而不是像watch 那样“定期”运行。

#!/bin/sh

tail -F /var/log/somelogfile | while read line; do
  if echo "$line" | grep -q '[Ss]ome.regex'; then
    # do your stuff
  fi
done

请注意,tail -F 将继续跟踪日志文件,即使它被 newsyslog 或 logrotate 轮换。您想使用它而不是小写的tail -f。详情请查看man tail

也就是说,如果您确实想定期运行命令,则提供的其他答案可以转换为简短的 shell 脚本:

#!/bin/sh
if [ -z "$2" ]; then
  echo "Usage: $0 SECONDS COMMAND" >&2
  exit 1
fi

SECONDS=$1
shift 1
while sleep $SECONDS; do
  clear
  $*
done

【讨论】:

不幸的是,这个 shell 脚本不适用于 bash 扩展参数,例如:watch 2 cat * @CodeCommander - 命令行 watch 2 cat * 会在运行脚本之前扩展参数,因此在包含文件“foo”和“bar”的目录中,您将每 2 秒运行一次 cat foo bar。你期待什么行为? @ghoti 我只是指出该行为与 Ubuntu 上的 watch 命令不同。 Ubuntu版本显然每两秒运行一次命令(每次运行时扩展参数),这个脚本在运行之前扩展了参数,然后每两秒使用相同的参数运行。因此,如果您想查看正在添加和删除文件的目录中的文件,则此脚本无济于事。但是,当您不使用扩展参数时,它很有用。 :) @CodeCommander,我认为你错了。 Bash(如 sh)扩展 * 而不将其传递给您运行的命令。尝试在一个窗口中运行:mkdir /tmp/zz; touch /tmp/zz/foo; watch -n 2 ls -l /tmp/zz/*。当它运行时,您可以在另一个窗口中touch /tmp/zz/bar。看看你的“手表”是否在第一个窗口中看到了变化。我不认为它会。它不适合我。这与 Ubuntu vs OSX 或 Linux vs Unix 无关,这是 bash 本身的行为。 @ghoti,你是对的。我误解了。即使使用 Linux watch 命令,您也需要使用引号:watch "ls -l /tmp/zz/*" 但如果您记得使用引号,它也适用于您的脚本。 :)【参考方案6】:

我将接受here的回答:

bash -c 'while [ 0 ]; do <your command>; sleep 5; done'

但是installing watch 你真的会更好,因为这不是很干净...

【讨论】:

现在更容易了,即使brew install watch【参考方案7】:

如果手表不想通过安装

brew install watch

还有另一个类似/复制版本对我来说安装和工作得很好

brew install visionmedia-watch

https://github.com/tj/watch

【讨论】:

支持visionmedia-watch - 它默认支持颜色。 watch 没有,有或没有 --color 选项。【参考方案8】:

或者,在你的 ~/.bashrc 文件中:

function watch 
    while :; do clear; date; echo; $@; sleep 2; done

【讨论】:

【参考方案9】:

为防止在您的主命令需要可感知的时间才能完成时闪烁,您可以捕获输出并仅在完成后清除屏幕。

function watch while :; do a=$($@); clear; echo "$(date)\n\n$a"; sleep 1;  done

然后使用它:

watch istats

【讨论】:

应该是echo -e 而不仅仅是echo,才能正确呈现这些换行符 感谢你们,对于限制安装包管理器(如 Brew)的客户端计算机,这是一个很好的答案。 事实上你可以通过执行你的命令来进一步减少闪烁,然后执行'date'并捕获那个o/p,然后然后清除......【参考方案10】:

试试这个:

#!/bin/bash
# usage: watch [-n integer] COMMAND

case $# in
    0)
        echo "Usage $0 [-n int] COMMAND"
        ;;
    *)      
        sleep=2;
        ;;
esac    

if [ "$1" == "-n" ]; then
    sleep=$2
    shift; shift
fi


while :; 
    do 
    clear; 
    echo "$(date) every $sleeps $@"; echo 
    $@; 
    sleep $sleep; 
done

【讨论】:

【参考方案11】:

这是一个稍有改动的版本of this answer:

检查有效参数 在顶部显示日期和持续时间标题 将“duration”参数移动到第一个参数,因此可以轻松地将复杂的命令作为剩余参数传递。

使用它:

将此保存到~/bin/watch 在终端中执行chmod 700 ~/bin/watch 使其可执行。 通过运行watch 1 echo "hi there" 尝试一下

~/bin/watch

#!/bin/bash

function show_help()

  echo ""
  echo "usage: watch [sleep duration in seconds] [command]"
  echo ""
  echo "e.g. To cat a file every second, run the following"
  echo ""
  echo "     watch 1 cat /tmp/it.txt" 
  exit;


function show_help_if_required()

  if [ "$1" == "help" ]
  then
      show_help
  fi
  if [ -z "$1" ]
    then
      show_help
  fi


function require_numeric_value()

  REG_EX='^[0-9]+$'
  if ! [[ $1 =~ $REG_EX ]] ; then
    show_help
  fi


show_help_if_required $1
require_numeric_value $1

DURATION=$1
shift

while :; do 
  clear
  echo "Updating every $DURATION seconds. Last updated $(date)"
  bash -c "$*"
  sleep $DURATION
done

【讨论】:

【参考方案12】:

使用Nix 包管理器!

安装 Nix,然后执行 nix-env -iA nixpkgs.watch,在完成安装说明(包括在您的 shell 中获取 . "$HOME/.nix-profile/etc/profile.d/nix.sh")后,它应该可以使用了。

【讨论】:

以上是关于OS X Bash,“监视”命令的主要内容,如果未能解决你的问题,请参考以下文章

mac os x配置adb命令的方法,苹果电脑设置adb命令的方法

防止事件监视器 OS X 中出现错误“放克”声音

sh watch是一个linux bash脚本,用于递归监视文件修改并在发生更改时执行bash命令

sh react是一个linux bash脚本,用于递归监视文件修改并在发生更改时执行bash命令

envsubst:在 Mac OS X 10.8 上找不到命令

修复 Linux / Unix / OS X / BSD 系统控制台上的显示乱码 | Linux 中国