ELisp: Call Shell Command

By Xah Lee. Date: . Last updated: .

Call Shell Command, Wait, Get Result

shell-command
Call a shell command, wait for it to finish.
; call a shell command
(shell-command "ls")
shell-command-to-string
Call a shell command, wait for it to finish, get its output.
; call a shell command and get its output
(shell-command-to-string "ls")

Start External Process

shell-command start a shell program to launch apps. More efficient is to launch external app directly. Also, you do not have to deal with complicated character escapes in arg or file name involvig apostrophe, quote, backslash.

call-process
(call-process PROGRAM &optional INFILE DESTINATION DISPLAY &rest ARGS)

Call PROGRAM in separate process, wait for it to finish. (unless DESTINATION is 0). PROGRAM is searched in exec-path

  • INFILE (nil means `null-device') is the input file (a relative path). see also call-process-region
  • DESTINATION is a buffer for output (including standard error.).
    • Or t for current buffer.
    • Or nil for discard output.
    • Or 0 for don't wait for the program to terminate..
    • Or (:file FILE) means write to file. (overwrite existing)
    • Or (REAL-BUFFER STDERR-FILE). (See elisp manual.)
  • DISPLAY non-nil means redisplay buffer as output is inserted.
  • ARGS are strings passed as command arguments to PROGRAM. (each is a string). If you have a list, use apply. [see ELisp: Apply Function (List to Args)]
;; example of call-process on linux
;; passing it a file path
(cond
 ((eq system-type 'windows-nt)
  nil)
 ((eq system-type 'darwin)
  nil)
 ((eq system-type 'gnu/linux)
  (call-process
   shell-file-name nil 0 nil
   shell-command-switch
   (format "%s %s"
           "xdg-open"
           (file-name-directory xpath)))))
;; example of call-process
;; and start-process
;; , when you need to feed it a lot file names

(let ((xoutBuf (get-buffer-create "*xah remove metadata output*"))
      (xshortNames (mapcar 'file-relative-name FileList)))
  (if Wait-p
      (apply
       'call-process
       (append
        (list "exiftool" nil xoutBuf t "-all=" "-overwrite_original")
        xshortNames nil))
    (let ((process-connection-type nil))
      (apply
       'start-process
       (append
        (list "exiftool" xoutBuf "exiftool" "-all=" "-overwrite_original")
        xshortNames nil))))
  (princ "Called xah-dired-remove-all-metadata"))
start-process
(start-process NAME BUFFER PROGRAM &rest PROGRAM-ARGS)

Start a program in a subprocess. (do not wait for it to finish) Return the process object for it.

  • NAME is name for process. Can be any.
  • BUFFER is the buffer (or buffer name) for process output (both standard output and standard error streams). Or nil.
  • PROGRAM is the program file name to start. It is searched for in exec-path. If nil, just associate a pty with the buffer.
  • PROGRAM-ARGS are arguments (each is a string). If you have a list, use apply. [see ELisp: Apply Function (List to Args)]
;; example of start-process and call-process

;; open a list of files in operating system's default app
(cond
 ((eq system-type 'windows-nt)
  (let ((xoutBuf (get-buffer-create "*xah open in external app*"))
        (xcmdlist (list "PowerShell" "-Command" "Invoke-Item" "-LiteralPath")))
    (mapc
     (lambda (x)
       (message "%s" x)
       (apply
        'start-process
        (append
         (list "xah open in external app" xoutBuf) xcmdlist
         (list (format "'%s'" (if (string-match "'" x) (replace-match "`'" t t x) x))) nil)))
     xfileList)))
 ((eq system-type 'darwin)
  (mapc (lambda (xfpath) (shell-command (concat "open " (shell-quote-argument xfpath)))) xfileList))
 ((eq system-type 'gnu/linux)
  (mapc
   (lambda (xfpath)
     (call-process
      shell-file-name nil 0 nil
      shell-command-switch
      (format "%s %s"
              "xdg-open"
              (shell-quote-argument xfpath))))
   xfileList))
 ((eq system-type 'berkeley-unix)
  (mapc
   (lambda (xfpath)
     (let ((process-connection-type nil))
       (start-process "" nil "xdg-open" xfpath)))
   xfileList)))
start-process-shell-command
(start-process-shell-command NAME BUFFER COMMAND)

same as start-process, but use a single string for the external command and args.

make-process
(make-process &rest ARGS)

The core function for creating process. similar to start-process. See elisp manual.

Reference