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.
The problem is that tokens like
~,*, and|aren’t processed/expanded by thelsprogram. Since the tokens aren’t processed,lsis 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
lscommand in a shell (much easier):so
Edit: Clarified some issues, like mentioning that
/bin/shdoesn’t do~expansion.