This doesn't seem to work in M-x shell
$ watch 'grep "FIX" /tmp/output | tail -n 5'
I see Every 2.0s: grep "FIX" /tmp/output | tail -n 5
and I see My-hostname.local: Tue Aug 28 19:09:22 2018
on screen.
Whats the emacs way of doing it?
This doesn't seem to work in M-x shell
$ watch 'grep "FIX" /tmp/output | tail -n 5'
I see Every 2.0s: grep "FIX" /tmp/output | tail -n 5
and I see My-hostname.local: Tue Aug 28 19:09:22 2018
on screen.
Whats the emacs way of doing it?
As commented, watch
needs to run in a terminal so that it can do all the fancy things that it does. In Emacs, that means running it via term
.
The very simplest thing is to invoke it from a shell running in M-x term
You can also run the watch
process directly in the terminal, but because the command needs arguments, doing that requires a custom wrapper along the lines of https://emacs.stackexchange.com/a/18678/454. Using the my-terminal-run
command in that answer, you could just type your ad-hoc watch
command at the prompt (or indeed any other command).
You can also write a wrapper specifically for watch
. The following Emacs command has a similar basis to the examples in the linked answer, but adds additional code for trivially dismissing and killing the buffer.
(defvar watch-history nil)
(defun watch (command &optional name)
"Runs \"watch COMMAND\" in a `term' buffer. \"q\" to exit."
(interactive
(list (read-from-minibuffer "watch " nil nil nil 'watch-history)))
(let* ((name (or name (concat "watch " command)))
(switches (split-string-and-unquote command))
(termbuf (apply 'make-term name "watch" nil switches))
(proc (get-buffer-process termbuf)))
(set-buffer termbuf)
(term-mode)
(term-char-mode)
(setq show-trailing-whitespace nil)
;; Kill the process interactively with "q".
(set-process-query-on-exit-flag proc nil)
(let ((map (make-sparse-keymap))
(cmdquit (make-symbol "watch-quit")))
(put cmdquit 'function-documentation "Kill the `watch' buffer.")
(put cmdquit 'interactive-form '(interactive))
(fset cmdquit (apply-partially 'kill-process proc))
(set-keymap-parent map (current-local-map))
(define-key map (kbd "q") cmdquit)
(use-local-map map))
;; Kill the buffer automatically when the process is killed.
(set-process-sentinel
proc (lambda (process signal)
(and (memq (process-status process) '(exit signal))
(buffer-live-p (process-buffer process))
(kill-buffer (process-buffer process)))))
;; Display the buffer.
(switch-to-buffer termbuf)))
An alternative solution:
(with-eval-after-load 'em-term
(add-to-list 'eshell-visual-commands "watch"))
To run command like watch -d date
, issue:
M-x eshell-command RET watch -d date RET
The watch
command requires a terminal emulator, which usually needs control keyboard events by itself, thus most Emacs key bindings will not work. Emacs provides a terminal emulator via M-x term
. If you must run commands like watch
within Emacs, you have to use it. I don't think you have other choice.