手表只监控可见输出吗?

手表只监控可见输出吗?

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 存储库安装的。

答案1

我发现这个帖子的标题是:Bug#225549:监视 stderr。该线程来自 2008 年,但看起来旧版本不支持观看 STDOUT 以外的任何内容。

所以我们仅限于 STDOUT。至于可见性,info watch其中有很多语言,man 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,您可以看到watch读取命令的输出ls,因此它在内部删除了更改。

在我删除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

答案2

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

我很确定你在追求inotify 工具

我的联机帮助页手表, 从procps-ng,说

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

相关内容