关于macos:OSX bash,’watch’命令

OSX bash, 'watch' command

我正在寻找在mac osx上复制linux"watch"命令的最佳方法。我想每隔几秒钟运行一个命令,使用"tail"和"sed"对输出文件的内容进行模式匹配。

我在Mac电脑上的最佳选择是什么?不下载软件也能做到吗?


安装了自制啤酒:

brew install watch


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

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

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

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

1
2
3
4
5
6
7
8
9
10
#!/bin/bash
# usage: watch.sh <your_command> <sleep_duration>

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


使用端口:

1
$ sudo port install watch


上面的shell可以做到这一点,甚至可以将它们转换为别名(可能需要包装成函数来处理参数)。

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

实例:

1
2
myWatch 1 ls ## self-explanatory
myWatch 5"ls -lF $HOME" ## every 5 seconds, list out home dir; double-quotes around command to keep its args together

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

1
brew install watch

可能"手表"不是你想要的。你可能想寻求帮助来解决你的问题,而不是实现你的解决方案!:)

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

1
2
3
4
5
6
7
#!/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将继续跟踪日志文件,即使它被newsylog或logrotate旋转。你想用这个来代替小写的tail -F。详细信息请查看man tail

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

1
2
3
4
5
6
7
8
9
10
11
12
#!/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


从这里回答:

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

但你最好还是安装手表,因为这不是很干净。


如果Watch不想通过安装

1
brew install watch

还有另一个相似的/复制版本,它为我完美地安装和工作。

1
brew install visionmedia-watch

网址:https://github.com/tj/watch


或者,在你的~/.bashrc

1
2
3
function watch {
    while :; do clear; date; echo; $@; sleep 2; done
}

我也有类似的问题。

当我在谷歌上搜索时,我最近发现了这个链接。这不完全是"安装软件",只是获取"watch"命令的二进制文件。

链接是osx的get watch命令


使用NIX包管理器!

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


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


function watch {while :; do a=$($@); clear; echo"$(date)

$a"; sleep 1; done}

然后由:watch istats使用


试试这个:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#!/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 ${sleep}s $@"; echo
    $@;
    sleep $sleep;
done

下面是这个答案的一个稍有变化的版本:

  • 检查有效参数
  • 在顶部显示日期和工期标题
  • 将"duration"参数移动为第一个参数,以便可以轻松地将复杂命令作为剩余参数传递。

使用它:

  • 把这个存到~/bin/watch
  • 在终端中执行chmod 700 ~/bin/watch,使其可执行。
  • 运行watch 1 echo"hi there"试试看。

行李/手表

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
#!/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