如果我在Emacs Lisp中异步执行一个shell命令,像这样:
(shell-command "mycommand &")
有没有办法在继续之前等待命令生成输出?对于我的当前应用程序,等待命令生成任何输出可能足够了,但理想情况下,我想捕获输出以进行其他处理。这个可能吗?
(shell-command "mycommand &")
有没有办法在继续之前等待命令生成输出?对于我的当前应用程序,等待命令生成任何输出可能足够了,但理想情况下,我想捕获输出以进行其他处理。这个可能吗?
comint-output-filter-functions
变量,该变量包含在输出插入到缓冲区后要调用的函数。(add-hook 'comint-output-filter-functions '(lambda (txt) (message "hello")))
async-shell-command
。这将异步执行您的命令而无需使用&符号。您的命令输出将发送到缓冲区*Async Shell Command*
。make-comint-in-buffer
一起运行异步命令并在执行时获取命令的输出。 - jcubic*scratch*
缓冲区并进行eval-region
,但请确保分割窗口并显示*Messages*
缓冲区可见,以便您可以看到发生了什么。;; this is emacs lisp (and a comment line)
(defvar my-callback-got-some-already nil)
(defun my-callback ()
(message "callback ran at %s" (current-time-string)))
(defun my-filter-waits-for-first-time-input (proc string)
(unless my-callback-got-some-already
(setq my-callback-got-some-already t)
;; do your one-time thing
(my-callback))
;; insert into the associated buffer as if no process filter was
;; registered
(with-current-buffer (process-buffer proc)
(let ((moving (= (point) (process-mark proc))))
(save-excursion
;; Insert the text, advancing the process marker.
(goto-char (process-mark proc))
(insert string)
(set-marker (process-mark proc) (point)))
(if moving (goto-char (process-mark proc))))))
(defun async-callback-test-harness ()
(interactive)
(let ((process-handle "async-callback-test")
(associated-process-buffer "*async-callback-test*")
(command "ls")
(busy-loop-var ""))
(setq my-callback-got-some-already nil)
(message "start test %s" (current-time-string))
(start-process process-handle associated-process-buffer command)
;; Supposedly async but Emacs doesn't get the input until
;; "Emacs is waiting" so the following set-process-filter
;; can be registered in time.
;; To prove the point, make emacs busy loop to show that the
;; emacs doesn't drop its input and
;; the callback will get the unskipped input.
(switch-to-buffer associated-process-buffer)
(dotimes (k 2000) ; about two seconds on my machine
(setq busy-loop-var (concat busy-loop-var "busy looping...")))
(message "done busy waiting %s" (current-time-string))
(set-process-filter (get-process process-handle)
'my-filter-waits-for-first-time-input)
nil))
;; run it!
(async-callback-test-harness)