Überwacht watch nur die sichtbare Ausgabe?

12

Ist watchnur die sichtbare Ausgabe eines Befehls überwachen? Angenommen, ich befinde mich in einem Verzeichnis mit folgendem Inhalt:

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

Beim Ausführen watch -g ls -1erwarte ich, dass es beendet wird, wenn eine Datei hinzugefügt oder entfernt wird. Was tatsächlich passiert, ist, dass es nur dann beendet wird, wenn die betreffende Datei in der Terminalausgabe von watch:

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

a
b
c
d
e
f

Das Löschen der Datei m, die aufgrund der Größe meines Terminals nicht sichtbar ist, führt zu nichts. Das Löschen einer sichtbaren Datei dführt watchbeispielsweise zum erwarteten Beenden.

Die -gFlagge ist so auf meiner manSeite erklärt:

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

Was ist los? Ist das normal? Wie kann ich watchBefehle mit langer Ausgabe verwenden? Ich benutze watch from procps-ng 3.3.4das, was von den Debian-Repos installiert wurde.

terdon
quelle
Was bedeutet die -gOption zu watchtun? Ich finde es nicht in meiner Version vonwatch
Iruvar
@ 1_CR siehe aktualisierte Frage, sollte es dazu führen, dass es beendet wird, wenn sich die Ausgabe ändert. Es funktioniert wie angekündigt, wenn die Änderung auf dem Bildschirm sichtbar ist.
Terdon

Antworten:

9

Ich fand diesen Thread mit dem Titel: Bug # 225549: watch monitor stderr . Dieser Thread stammt aus dem Jahr 2008, aber es sieht so aus, als ob ältere Versionen nichts anderes als STDOUT unterstützen.

Wir sind also auf STDOUT beschränkt. Was das Sichtbare anbelangt, gibt es in der Sprache viel, info watchund man watchdas lässt mich denken, dass Ihre Beobachtung / Annahme richtig ist.

Auszug

   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.

Auch dieses Bit unter 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.

Wenn ich raten müsste, würde ich denken, dass sie die sichtbaren Bits in einem Puffer zwischen den Läufen speichern und dann nur diese Zeichen analysieren.

EDIT # 1

Ich habe dies weiter mit debuggt straceund Sie können sehen watch, wie die Ausgabe des lsBefehls gelesen wird, damit die Änderung intern verworfen wird.

bevor ich die mdatei lösche

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

nachdem die mDatei gelöscht wurde

--- 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
quelle
Ja, es scheint nur seltsam, es macht es unmöglich, so etwas zu machen watch -g foo; echo "Something changed!". Es scheint ein seltsam lähmender Fehler in einem so etablierten Programm zu sein.
terdon
@terdon - meine alte Version von Fedora hatte den -gSchalter nicht , aber ich habe es auf Ubuntu versucht und es verhält sich genauso.
slm
OK, das ist wirklich seltsam dann. Also überwacht und sieht es die Veränderung tatsächlich, es reagiert einfach nicht darauf! Auf jeden Fall ein Bug dann.
terdon
2

Ich erwarte, dass es beendet wird, wenn eine Datei hinzugefügt oder entfernt wird

Ich bin mir ziemlich sicher, dass Sie Inotify-Tools suchen .

Meine Manpage für watch von procps-ng sagt

watch führt den Befehl wiederholt aus und zeigt seine Ausgabe und Fehler an (der erste Bildschirm ist voll) .

jdoch
quelle
Darum fragt er nicht, er versucht das Verhalten eines Updates zu verstehen, das über STDOUT angezeigt wird, ist aber im Terminal nicht sichtbar. B / C hat er die Größe so geändert, dass die Ausgabe, die geändert wird, "aus" ist Bildschirm". Die meisten, mit denen ich heute darüber gesprochen habe, hätten erwartet watch, dass sie sich als OP verhalten und mit der Änderung aussteigen.
slm
Ja, auch darüber haben wir bereits gesprochen. Ich habe denselben Text in meiner Antwort hervorgehoben. Ich kenne Terdon ziemlich gut und an dieser Stelle möchte er den Grund dafür wissen.
slm
Ich stimme zu, es ist nicht die Antwort auf seine Frage, aber es ist die Lösung für sein Problem.
14.
Du meinst mit inotify? Er ist nicht danach, er will wissen, warum er watchsich so verhält. Er weiß über Inotify Bescheid.
slm
Das ist seine Frage. Was er damit zu tun versucht, ist das, was ich zitiert habe: Warten Sie, bis eine Datei hinzugefügt oder entfernt wurde. Watch ist nicht das Werkzeug für diesen Job.
14.