Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In Emacs-lisp, what is the correct way to use call-process on an ls command?

Tags:

emacs

lisp

I want to execute the following shell command in emacs-lisp:

ls -t ~/org *.txt | head -5

My attempt at the following:

(call-process "ls" nil t nil "-t" "~/org" "*.txt" "| head -5")

results in

ls: ~/org: No such file or directory
ls: *.txt: No such file or directory
ls: |head -5: No such file or directory

Any help would be greatly appreciated.

like image 227
eatloaf Avatar asked Feb 01 '11 04:02

eatloaf


People also ask

How do I lisp in Emacs?

In a fresh Emacs window, type ESC-x lisp-interaction-mode . That will turn your buffer into a LISP terminal; pressing Ctrl+j will feed the s-expression that your cursor (called "point" in Emacs manuals' jargon) stands right behind to LISP, and will print the result.

How do I run a shell command in Emacs?

You can execute an external shell command from within Emacs using ` M-! ' ( 'shell-command' ). The output from the shell command is displayed in the minibuffer or in a separate buffer, depending on the output size.

What does #' mean in Emacs Lisp?

function (aka #' ) is used to quote functions, whereas quote (aka ' ) is used to quote data.

Is Emacs asynchronous?

Unfortunately Emacs has no asynchronous API for writing output to a process.


1 Answers

The problem is that tokens like ~, *, and | aren't processed/expanded by the ls program. Since the tokens aren't processed, ls is look for a file or directory literally called ~/org, a file or directory literally called *.txt, and a file or directory literally called | head -5. Thus the error message you received about `No such file or directory".

Those tokens are processed/expanded by the shell (like Bourne shell /bin/sh or Bash /bin/bash). Technically, interpretation of the tokens can be shell-specific, but most shell interpret at least some of the same standard tokens the same way, e.g. | means connecting programs together end-to-end to almost all shells. As a counterexample, Bourne shell (/bin/sh) does not do ~ tilde/home-directory expansion.

If you want to get the expansions, you have to get your calling program to do the expansion itself like a shell would (hard work) or run your ls command in a shell (much easier):

/bin/bash -c "ls -t ~/org *.txt | head -5"

so

(call-process "/bin/bash" nil t nil "-c" "ls -t ~/org *.txt | head -5")

Edit: Clarified some issues, like mentioning that /bin/sh doesn't do ~ expansion.

like image 138
Bert F Avatar answered Sep 21 '22 03:09

Bert F