在Emacs-lisp中,在ls命令中使用call-process的正确方法是什么?

eat*_*oaf 13 lisp emacs

我想在emacs-lisp中执行以下shell命令:

ls -t ~/org *.txt | head -5
Run Code Online (Sandbox Code Playgroud)

我尝试以下方面:

(call-process "ls" nil t nil "-t" "~/org" "*.txt" "| head -5")
Run Code Online (Sandbox Code Playgroud)

结果是

ls: ~/org: No such file or directory
ls: *.txt: No such file or directory
ls: |head -5: No such file or directory
Run Code Online (Sandbox Code Playgroud)

任何帮助将不胜感激.

Ber*_*t F 19

问题是代码喜欢~,*并且|不被ls程序处理/扩展.由于未处理令牌,ls因此查找字面上称为~/org的文件或目录,字面上称为*.txt的文件或目录,以及字面上称为的文件或目录| head -5.因此,您收到的关于"没有这样的文件或目录"的错误消息.

这些令牌由shell处理/扩展(如Bourne shell/bin/sh或Bash/bin/bash).从技术上讲,令牌的解释可以是特定于shell的,但是大多数shell以相同的方式解释至少一些相同的标准令牌,例如|意味着将程序端到端连接到几乎所有的shell.作为一个反例,Bourne shell(/ bin/sh)不会进行~波形/主目录扩展.

如果你想获得扩展,你必须让你的调用程序像shell一样进行扩展(努力工作)或者ls在shell中运行你的命令(更容易):

/bin/bash -c "ls -t ~/org *.txt | head -5"
Run Code Online (Sandbox Code Playgroud)

所以

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

编辑:澄清了一些问题,比如提到/bin/sh不做~扩展.


R. *_*lon 12

根据您的使用情况,如果您发现自己想要执行shell命令并且经常在新缓冲区中使输出可用,您也可以使用该shell-command功能.在您的示例中,它看起来像这样:

(shell-command "ls -t ~/org *.txt | head -5")
Run Code Online (Sandbox Code Playgroud)

但是,要将其插入当前缓冲区,则需要current-prefix-arg使用类似的东西手动设置(universal-argument),这有点像黑客攻击.另一方面,如果你只想在某个地方输出你可以得到它并处理它,shell-command它将与其他任何东西一样工作.