手表仅监视可见输出吗?


12

难道watch只监视命令的可见的输出?假设我位于一个包含以下内容的目录中:

$ ls
a  b  c  d  e  f  g  h  i  j  k  l  m  n

如果我运行,watch -g ls -1我希望它在添加或删除文件后退出。实际发生的情况是,只有当相关文件在以下终端输出中可见时,它才会退出watch

$ watch -g ls -1
Every 2.0s: ls -1                   Wed Nov 13 16:35:03 2013

a
b
c
d
e
f

删除文件m(由于终端的大小而看不到)不会执行任何操作。删除可见文件(例如d)会导致watch按预期退出。

-g因此,在我的man页面中解释了该标志:

   -g, --chgexit
          Exit when the output of command changes.

这是怎么回事?这正常吗?如何使用watch长输出的命令?我正在使用watch from procps-ng 3.3.4从Debian仓库安装的软件。


-g选项有watch什么作用?我在watch
iruvar的

@ 1_CR看到更新的问题,当输出更改时,它应该导致它退出。当更改在屏幕上可见时,它的工作与广告中所宣传的一样。
terdon

Answers:


9

我发现此线程的标题为:Bug#225549:具有watch monitor stderr。该线程来自2008年,但看起来旧版本不支持观看STDOUT以外的任何内容。

因此,我们仅限于STDOUT。至于可见的语言info watchman watch这让我觉得您的观察/假设是正确的。

摘抄

   watch runs command repeatedly, displaying its output (the first screen‐
   full).   This  allows you to watch the program output change over time.
   By default, the program is run every 2 seconds; use -n or --interval to
   specify a different interval.

同样在BUGS下的这一位:

BUGS
       Upon  terminal resize, the screen will not be correctly repainted until
       the next scheduled update.  All --differences highlighting is  lost  on
       that update as well.

如果我不得不猜测,我认为它们是在运行之间将可见位存储在缓冲区中,然后仅分析那些字符。

编辑#1

我使用了进一步的调试功能strace,您可以看到watchls命令中读取了输出,因此它在内部删除了更改。

在我删除m文件之前

$ strace -o w.log watch -g 'ls -1'
read(3, "a\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\nw.lo"..., 4096) = 34
close(3)                                = 0
--- SIGCHLD (Child exited) @ 0 (0) ---
munmap(0x7f4da83af000, 4096)            = 0
wait4(31011, [{WIFEXITED(s) && WEXITSTATUS(s) == 0}], 0, NULL) = 31011
rt_sigaction(SIGTSTP, {SIG_IGN, [], SA_RESTORER|SA_RESTART, 0x7f4da79b94a0}, {0x7f4da7f81ee0, [], SA_RESTORER|SA_RESTART, 0x7f4da79b94a0}, 8) = 0
write(1, "\33[H\33[2JEvery 2.0s: ls -1\33[1;140H"..., 119) = 119
rt_sigaction(SIGTSTP, {0x7f4da7f81ee0, [], SA_RESTORER|SA_RESTART, 0x7f4da79b94a0}, NULL, 8) = 0
nanosleep({2, 0}, NULL)                 = 0
stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=3519, ...}) = 0
pipe([3, 4])                            = 0
clone(child_stack=0, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7f4da839f9d0) = 31014
close(4)                                = 0
fcntl(3, F_GETFL)                       = 0 (flags O_RDONLY)
fstat(3, {st_mode=S_IFIFO|0600, st_size=0, ...}) = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f4da83af000
lseek(3, 0, SEEK_CUR)                   = -1 ESPIPE (Illegal seek)
read(3, "a\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nm\nn\nw.lo"..., 4096) = 34
close(3)                                = 0
munmap(0x7f4da83af000, 4096)            = 0
--- SIGCHLD (Child exited) @ 0 (0) ---

m删除文件后

--- SIGCHLD (Child exited) @ 0 (0) ---
rt_sigaction(SIGTSTP, {SIG_IGN, [], SA_RESTORER|SA_RESTART, 0x7f4da79b94a0}, {0x7f4da7f81ee0, [], SA_RESTORER|SA_RESTART, 0x7f4da79b94a0}, 8) = 0
poll([{fd=0, events=POLLIN}], 1, 0)     = 0 (Timeout)
poll([{fd=0, events=POLLIN}], 1, 0)     = 0 (Timeout)
write(1, "\33[1;158H8\33[11;163H", 18)  = 18
rt_sigaction(SIGTSTP, {0x7f4da7f81ee0, [], SA_RESTORER|SA_RESTART, 0x7f4da79b94a0}, NULL, 8) = 0
nanosleep({2, 0}, NULL)                 = 0
stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=3519, ...}) = 0
pipe([3, 4])                            = 0
clone(child_stack=0, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7f4da839f9d0) = 31028
close(4)                                = 0
fcntl(3, F_GETFL)                       = 0 (flags O_RDONLY)
fstat(3, {st_mode=S_IFIFO|0600, st_size=0, ...}) = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f4da83af000
lseek(3, 0, SEEK_CUR)                   = -1 ESPIPE (Illegal seek)
read(3, "a\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk\nl\nn\nw.log\n", 4096) = 32
close(3)                                = 0
--- SIGCHLD (Child exited) @ 0 (0) ---
munmap(0x7f4da83af000, 4096)            = 0
wait4(31028, [{WIFEXITED(s) && WEXITSTATUS(s) == 0}], 0, NULL) = 31028

是的,看起来好像很奇怪,它使得无法运行类似的东西watch -g foo; echo "Something changed!"。在这样一个既定的程序中,这似乎是一个令人毛骨悚然的错误。
terdon

@terdon-我的Fedora的较早版本没有此-g开关,但我在Ubuntu上尝试过,其行为相同。
slm

好,那真的很奇怪。因此,它实际上监视并查看更改,但是它没有反应!那肯定是一个错误。
terdon

2

如果添加或删除文件,我希望它会退出

我很确定您正在使用inotify-tools

我来自procps-ng的观看手册,说

watch反复运行命令,显示其输出和错误(第一个全屏显示)


这不是他要问的,他试图了解正在通过STDOUT显示的更新的行为,但是在终端b / c中不可见,因此他调整了大小,以便更改的输出为“关闭”。屏幕”。我今天与之讨论过的大多数人都希望watch扮演OP,并随着变更退出。
slm

是的,我们也已经讨论过了,我在答案中强调了相同的文本。我非常了解Terdon,在这一点上,他想知道原因。
slm

我同意这不是他问题的答案,但这是他问题的解决方案。
jthill 2013年

您是说使用inotify?那不是他所追求的,他想知道为什么watch这样做。他了解inotify。
slm

那是他的问题。我要引用的是他正在尝试做的事情:等待文件被添加或删除。监视不是完成此任务的工具。
jthill 2013年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.