0

I'm using call-process in an emacs/lisp file (in Spacemacs) to run an external command and write its output to a file. It works when I hard code the path like this:

(call-process "/bin/ls" nil '(:file "/Users/alan/Desktop/tmp.txt"))

However, I can't get it to work when I use a variable for the path.

When I do:

(defvar path-to-output-test nil
  "Path to send the file to")

(setq path-to-output-test
      "/Users/alan/Desktop/tmp-4.txt"
      )

(call-process "/bin/ls" nil '(:file path-to-output-test))

I get:

setq: Wrong type argument: stringp, path-to-output-test

I tried setting the variable directly with:

(defvar path-to-output-test
  "/Users/alan/Desktop/tmp-4.txt"
  "Path to send the file to")

And by adding a concat with:

(setq path-to-output-test
      (concat "/Users/alan/Desktop/tmp-5.txt" )
      )

I also tried a bunch of other combinations:

(call-process "/bin/ls" nil '(:file path-to-output-test))
(call-process "/bin/ls" nil '(:file 'path-to-output-test))
(call-process "/bin/ls" nil '(:file `path-to-output-test))

(call-process "/bin/ls" nil '((:file path-to-output-test)))
(call-process "/bin/ls" nil '((:file 'path-to-output-test)))
(call-process "/bin/ls" nil '((:file `path-to-output-test)))

(call-process "/bin/ls" nil '('(:file path-to-output-test)))
(call-process "/bin/ls" nil '('(:file 'path-to-output-test)))
(call-process "/bin/ls" nil '('(:file `path-to-output-test)))

(call-process "/bin/ls" nil '(stringp (:file 'path-to-output-test)))
(call-process "/bin/ls" nil '(stringp '(:file 'path-to-output-test)))
(call-process "/bin/ls" nil '(stringp `(:file 'path-to-output-test)))

(call-process "/bin/ls" nil '(:file (string path-to-output-test)))
(call-process "/bin/ls" nil '(:file '(string path-to-output-test)))
(call-process "/bin/ls" nil '(:file `(string path-to-output-test)))

(call-process "/bin/ls" nil '(:file (stringp path-to-output-test)))
(call-process "/bin/ls" nil '(:file '(stringp path-to-output-test)))
(call-process "/bin/ls" nil '(:file `(stringp path-to-output-test)))

(call-process "/bin/ls" nil '(:file (make-string path-to-output-test)))
(call-process "/bin/ls" nil '(:file '(make-string path-to-output-test)))
(call-process "/bin/ls" nil '(:file `(make-string path-to-output-test)))

(call-process "/bin/ls" nil '(:file (make-string 'path-to-output-test)))
(call-process "/bin/ls" nil '(:file '(make-string 'path-to-output-test)))
(call-process "/bin/ls" nil '(:file `(make-string 'path-to-output-test)))

(call-process "/bin/ls" nil '(:file (prin1 path-to-output-test)))
(call-process "/bin/ls" nil '(:file '(prin1 path-to-output-test)))
(call-process "/bin/ls" nil '(:file `(prin1 path-to-output-test)))

(call-process "/bin/ls" nil '(:file (concat path-to-output-test)))
(call-process "/bin/ls" nil '(:file '(concat path-to-output-test)))
(call-process "/bin/ls" nil '(:file `(concat path-to-output-test)))

(call-process "/bin/ls" nil `(:file path-to-output-test))
(call-process "/bin/ls" nil `(:file 'path-to-output-test))
(call-process "/bin/ls" nil `(:file `path-to-output-test))

None of those worked. They all returned a similar error but with whatever code I was trying to use for the iteration.

These tries didn't throw an error, but they didn't output the file:

(call-process "/bin/ls" nil (stringp '(:file path-to-output-test)))
(call-process "/bin/ls" nil (stringp '(:file 'path-to-output-test)))
(call-process "/bin/ls" nil (stringp '(:file `path-to-output-test)))

I'm new to emacs/lisp and am out of ideas at this point.

NickD
  • 27,023
  • 3
  • 23
  • 42
  • This is a FAQ with many duplicates, which are unfortunately a bit hard to find unless you know the answer already. Here is one: https://emacs.stackexchange.com/questions/7481/how-to-evaluate-the-variables-before-adding-them-to-a-list – NickD May 30 '22 at 03:49
  • 1
    Does this answer your question? [How to evaluate the variables before adding them to a list?](https://emacs.stackexchange.com/questions/7481/how-to-evaluate-the-variables-before-adding-them-to-a-list) – NickD May 30 '22 at 03:49
  • Maybe? I'm still trying to parse the answer you linked. The below accepted answer did work. I didn't understand it, but someone was kind enough to explain it, so I'm starting to get my head around it – Alan W. Smith May 30 '22 at 16:54
  • 1
    Yes, it is unfortunately a bit of a hydra: you see all the heads waving but initially not the body until you have some experience. But the body is: how can I get the value of a variable inside a quoted list? You need to quote the list (because it's just data, not a function call), but you want to evaluate *parts* of that list. – NickD May 30 '22 at 16:59

1 Answers1

1

You should use Backquote

(call-process "/bin/ls" nil `(:file ,path-to-output-test))

or list directly

(call-process "/bin/ls" nil (list :file path-to-output-test))
Tianshu Wang
  • 1,724
  • 4
  • 7