Часы только контролируют видимый вывод?

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 см. Обновленный вопрос, он должен вызывать выход при изменении выходных данных. Он работает так, как рекламируется, когда изменения видны на экране.
Тердон

Ответы:

9

Я нашел эту тему под названием: Ошибка # 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
       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
SLM
источник
Да, это просто кажется странным, это делает невозможным запуск чего-то подобного watch -g foo; echo "Something changed!". Кажется странно вредной ошибкой в ​​такой установленной программе.
Тердон
@terdon - моя старая версия Fedora не имела -gпереключателя, но я попробовал его на Ubuntu, и он ведет себя так же.
SLM
ОК, тогда это действительно странно. Так что он действительно отслеживает и видит изменения, он просто не реагирует на это! Определенно ошибка тогда.
Тердон
2

Я ожидаю, что он завершится, если файл будет добавлен или удален

Я почти уверен, что вам нужны инструменты inotify .

Моя man-страница для часов от procps-ng говорит

watch запускает команду несколько раз, отображая ее вывод и ошибки (первый экран) .

jthill
источник
Это не то, о чем он спрашивает, он пытается понять, как происходит обновление, отображаемое через STDOUT, но он не виден в терминале, потому что он изменил размеры, так что изменяемый вывод «выключен». экран». Большинство из тех, с кем я обсуждал это сегодня, ожидали, что будут watchвести себя как ОП и выйдут с изменением.
SLM
Да, мы это уже обсуждали, я выделил этот же текст в своем ответе. Я достаточно хорошо знаю Тердона, и в этот момент он хочет знать причину.
SLM
Я согласен, что это не ответ на его вопрос, а решение его проблемы.
Jthill
Вы имеете в виду использование inotify? Это не то, что ему нужно, он хочет знать, почему так watchсебя ведет. Он знает о inotify.
SLM
Это его вопрос. То, что он пытается с этим сделать, - это то, что я процитировал: дождаться добавления или удаления файла. Смотреть не инструмент для этой работы.
до