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.
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.
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.
function (aka #' ) is used to quote functions, whereas quote (aka ' ) is used to quote data.
Unfortunately Emacs has no asynchronous API for writing output to a process.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With