O watch monitora somente a saída visível?

12

O watch monitora somente a saída visível de um comando? Digamos que eu esteja em um diretório com o seguinte conteúdo:

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

Se eu executar watch -g ls -1 , espero que saia se um arquivo for adicionado ou removido. O que realmente acontece é que sai somente se o arquivo em questão estiver visível na saída do terminal de watch :

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

a
b
c
d
e
f

Excluir o arquivo m , que não é visível por causa do tamanho do meu terminal, não faz nada. A exclusão de um arquivo visível, digamos d , faz com que watch seja o esperado.

O sinalizador -g é explicado assim na minha página man :

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

O que está acontecendo? Isso é normal? Como posso usar watch para comandos com saída longa? Estou usando o watch from procps-ng 3.3.4 que foi instalado a partir dos repositórios do Debian.

    
por terdon 13.11.2013 / 16:41

2 respostas

9

Eu encontrei este tópico intitulado: Bug # 225549: have veja o monitor stderr . Esse segmento é de 2008, mas parece que as versões mais antigas não suportam a visualização de algo diferente de STDOUT.

Então, estamos limitados a apenas STDOUT. Quanto ao visível, há muita linguagem no info watch e man watch que me fazem pensar que você observação / suposição está correta.

trecho

   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.

Além disso, este bit está em 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.

Se eu tivesse que adivinhar, pensaria que eles estavam armazenando os bits visíveis em um buffer entre execuções e, em seguida, analisando apenas esses caracteres.

EDIT # 1

Depurei isso ainda mais usando strace e você pode ver watch lendo a saída do comando ls , então está descartando internamente a alteração.

antes de excluir o arquivo 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, "[H[2JEvery 2.0s: ls -1[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) ---

após o arquivo m ser excluído

--- 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, "[1;158H8[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
    
por 13.11.2013 / 23:48
2

I expect it to exit if a file is added or removed

Tenho certeza de que você está atrás das inotify-tools .

Minha página de manual para assistir , de procps-ng , diz

watch runs command repeatedly, displaying its output and errors (the first screenfull).

    
por 14.11.2013 / 06:09

Tags