I am running a command that produces a few thousand lines of output, which I would like to store in a buffer. I want to run it in the background and be alerted when it is finished. The problem is that it typically takes of order 10 seconds to report back, when the command itself takes a second or less to run.
Here is a trivial example. I set up my command to produce 2000 lines of output
(setq bjm-cmd "find /Users/bjm/ -ls | head -2000")
then use following to save the output to a string and write to a buffer
(progn (message "shell-command-to-string") (message (format-time-string "%c" (current-time))) (with-temp-buffer (insert-string (shell-command-to-string bjm-cmd))) (message (format-time-string "%c" (current-time))))
This works effectively instantly.
Now if I instead run the command asynchronously:
(defun bjm-test-sentinel (process event) (if (string= event "finished\n") (message "finished") (message "failed")) (message (format-time-string "%c" (current-time)))) (progn (message "start-process-shell-command") (message (format-time-string "%c" (current-time))) (setq bjm-proc (start-process-shell-command "dummy" "dummy" bjm-cmd)) (set-process-sentinel bjm-proc #'bjm-test-sentinel))
it takes about 15 seconds to complete.
I presume this is because the sentinel is parsing the output in some way - right?
My work around is to redirect the output of my command to a file and then read the file into the buffer. i.e.
(setq bjm-cmd "find /Users/bjm/ -ls | head -2000 > /tmp/junk")
This runs quickly, but feels like a bit of a hack - is there a better way?
The context for this is that I am working on a package to call OS X spotlight using the ivy and counsel libraries, but I think the question is a generic one.