Watch

watch 是否只監視可見輸出?

  • March 25, 2018

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 儲存庫安裝的。

我發現這個文章的標題是:Bug#225549: have 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,您可以看到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

引用自:https://unix.stackexchange.com/questions/101041