O relógio monitora apenas a saída visível?


12

Será watchúnica monitorar 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 ele 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

A exclusão do arquivo m, que não é visível por causa do tamanho do meu terminal, não faz nada. Excluir um arquivo visível, digamos d, faz watchcom que saia conforme o esperado.

A -gbandeira é explicada assim na minha manpágina:

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

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


O que a -gopção watchfaz? Não o encontro na minha versão dowatch
iruvar 13/11/2013

@ 1_CR, veja a pergunta atualizada, deve sair quando a saída for alterada. Funciona como anunciado quando a alteração é visível na tela.
terdon

Respostas:


9

Encontrei este tópico intitulado: Bug # 225549: tenha watch monitor stderr . Esse segmento é de 2008, mas parece que versões mais antigas não suportam a observação de nada além de STDOUT.

Portanto, estamos limitados a apenas STDOUT. Quanto visível, há muita linguagem no info watche man watchisso me faz pensar que sua observação / suposição está correta.

excerto

   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.

Também este bit 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, acho que eles estavam armazenando os bits visíveis em um buffer entre as execuções e analisando apenas esses caracteres.

EDIT # 1

Eu depurei isso ainda mais usando stracee você pode ver watchlendo a saída do lscomando para que ele elimine internamente a alteração.

antes de excluir o marquivo

$ 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) ---

depois que o marquivo é 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, "\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

Sim, isso parece estranho, torna impossível executar algo parecido watch -g foo; echo "Something changed!". Parece um bug estranhamente incapacitante em um programa tão estabelecido.
terdon

@terdon - minha versão antiga do Fedora não tinha a -gopção, mas eu tentei no Ubuntu e se comporta da mesma maneira.
slm

OK, isso é realmente estranho então. Então ele realmente monitora e vê a mudança, simplesmente não reage a ela! Definitivamente um bug então.
terdon

2

Espero que saia se um arquivo for adicionado ou removido

Tenho certeza de que você está buscando ferramentas inotify .

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

O watch executa o comando repetidamente, exibindo sua saída e erros (a primeira tela cheia) .


Não é sobre isso que ele está perguntando, ele está tentando entender o comportamento de uma atualização que está sendo exibida via STDOUT, mas não é visível no terminal b / c, ele foi redimensionado para que a saída que está sendo alterada fique "desligada" tela". Quase todo mundo com quem eu discuti isso hoje teria se watchcomportado como o OP e sairia com a mudança.
slm

Sim, também já discutimos isso, destaquei o mesmo texto na minha resposta. Conheço Terdon razoavelmente bem e, nesse ponto, ele quer saber o motivo.
slm

Concordo que não é a resposta para a pergunta dele, mas é a solução para o problema dele.
jthill

Você quer dizer usar inotify? Não é isso que ele procura, ele quer saber por que watchse comporta dessa maneira. Ele sabe sobre inotificar.
slm

Essa é a pergunta dele. O que ele está tentando fazer é o que citei: aguarde a inclusão ou remoção de um arquivo. O relógio não é a ferramenta para esse trabalho.
jthill
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.