La montre surveille-t-elle uniquement la sortie visible?

12

Ne watchcontrôle que la sortie visible d'une commande? Disons que je suis dans un répertoire avec le contenu suivant:

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

Si je cours, watch -g ls -1je m'attends à ce qu'il se termine si un fichier est ajouté ou supprimé. Ce qui se passe réellement, c'est qu'il ne se ferme que si le fichier en question est visible dans la sortie du 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

La suppression du fichier m, qui n'est pas visible à cause de la taille de mon terminal, ne fait rien. Suppression d'un fichier visible, par exemple d, provoque la fermeture watchcomme prévu.

Le -gdrapeau s'explique ainsi dans ma manpage:

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

Que se passe-t-il? Est-ce normal? Comment puis-je utiliser watchpour des commandes avec une sortie longue? J'utilise watch from procps-ng 3.3.4ce qui a été installé à partir des dépôts Debian.

terdon
la source
Que fait l' -goption watch? Je ne le trouve pas dans ma version dewatch
iruvar
@ 1_CR voir la question mise à jour, cela devrait entraîner sa fermeture lorsque la sortie change. Cela fonctionne comme annoncé lorsque le changement est visible à l'écran.
terdon

Réponses:

9

J'ai trouvé ce fil intitulé: Bug # 225549: avoir un moniteur de surveillance stderr . Ce fil date de 2008, mais il semble que les anciennes versions ne prennent pas en charge la surveillance de quoi que ce soit d'autre que STDOUT.

Nous sommes donc limités à STDOUT. En ce qui concerne le visible, il y a beaucoup de langage dans le info watchet man watchcela me fait penser que votre observation / hypothèse est correcte.

extrait

   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.

Aussi ce bit sous 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.

Si je devais deviner, je penserais qu'ils stockaient les bits visibles dans un tampon entre les exécutions, puis analysaient uniquement ces caractères.

EDIT # 1

J'ai débogué cela plus en utilisant straceet vous pouvez voir la watchlecture de la sortie de la lscommande afin de supprimer en interne le changement.

avant de supprimer le mfichier

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

après la msuppression du fichier

--- 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
la source
Ouais, ça semble juste bizarre, ça rend impossible d'exécuter quelque chose comme ça watch -g foo; echo "Something changed!". Cela semble un bug étrangement invalidant dans un programme aussi établi.
terdon
@terdon - mon ancienne version de Fedora n'avait pas le -gcommutateur mais je l'ai essayé sur Ubuntu et il se comporte de la même manière.
slm
OK, c'est vraiment bizarre alors. Donc, il surveille et voit réellement le changement, il n'y réagit tout simplement pas! Certainement un bug alors.
terdon
2

Je m'attends à ce qu'il se ferme si un fichier est ajouté ou supprimé

Je suis presque sûr que vous recherchez les outils inotify .

Ma page de manuel pour la montre , de procps-ng , dit

watch runs command à plusieurs reprises, affichant sa sortie et ses erreurs (le premier écran) .

jthill
la source
Ce n'est pas ce qu'il demande, il essaie de comprendre le comportement d'une mise à jour se produisant, affiché via STDOUT, mais n'est pas visible dans le terminal b / c, il l'a redimensionné de sorte que la sortie qui est modifiée est "désactivée" écran". La plupart des gens avec qui j'en ai discuté aujourd'hui se seraient attendus watchà se comporter comme l'OP et à sortir avec le changement.
slm
Oui, nous avons déjà discuté de cela aussi, j'ai mis en évidence ce même texte dans ma réponse. Je connais assez bien Terdon et à ce stade, il veut savoir pourquoi.
slm
Je suis d'accord que ce n'est pas la réponse à sa question, mais c'est la solution à son problème.
2013 à 7h33
Tu veux dire utiliser inotify? Ce n'est pas ce qu'il cherche, il veut savoir pourquoi il watchse comporte ainsi. Il connaît l'inotification.
slm
Voilà sa question. Ce qu'il essaie d'en faire, c'est ce que j'ai cité: attendre qu'un fichier soit ajouté ou supprimé. La montre n'est pas l'outil pour ce travail.
2013