I'm trying to capture stderr separately from stdout for a (synchronous) process run from emacs. I've found one way of doing it based on some code copied from emacs'
shell-command function (I don't want to use
shell-command directly because there is no need for a shell and
shell-command puts stdout into a buffer):
(defun helm-dash-sql (db-path sql) "Run the sql command, parse the results and display errors" (helm-dash-parse-sql-results (with-output-to-string (let ((error-file (make-temp-file "helm-dash-errors-file"))) (call-process "sqlite3" nil (list standard-output error-file) nil ;; args for sqlite3: db-path sql) ;; display errors, stolen from emacs' `shell-command` function (when (and error-file (file-exists-p error-file)) (if (< 0 (nth 7 (file-attributes error-file))) (with-current-buffer (get-buffer-create "*helm-dash-errors*") (let ((pos-from-end (- (point-max) (point)))) (or (bobp) (insert "\f\n")) ;; Do no formatting while reading error file, ;; because that can run a shell command, and we ;; don't want that to cause an infinite recursion. (format-insert-file error-file nil) ;; Put point after the inserted errors. (goto-char (- (point-max) pos-from-end))) (display-buffer (current-buffer)))) (delete-file error-file))))))
However I suspect it could be done better in two ways:
It seems like this should be a solved problem and emacs should have a function that just "does the right thing" with stderr, but I can't find one. Is there such a function?
Every time a process is run
shell-commandcreates (and later deletes) a temp file in which to store stderr. We are slightly concerned that this could have a performance impact because multiple processes are run for every keypress while inside this
helmcommand. Is this likely to be an issue, and if so what is the best way around it?