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_command
和sleep_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>&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命令的方法
sh watch是一个linux bash脚本,用于递归监视文件修改并在发生更改时执行bash命令
sh react是一个linux bash脚本,用于递归监视文件修改并在发生更改时执行bash命令