在 Emacs eshell 命令中调用复杂的管道查找

Invoking a complex piped find within Emacs eshell-command

我正在尝试做一些看似简单的事情:创建一个 Emacs 函数来为我创建一个 TAGS 文件。有执行此操作的简单说明 here

(defun create-tags (dir-name)
 "Create tags file."
 (interactive "DDirectory: ")
 (eshell-command 
  (format "find %s -type f -name \"*.[ch]\" | etags -" dir-name)))

问题是我需要 "cpp" 个文件而不是 "c"。这意味着我的查找命令必须更改为:

find %s -type f -iname "*.cpp" -or -iname "*.h"

在命令行上效果很好。我遇到的问题是 eshell 似乎根本不喜欢那样。当我执行这个函数时,我不断得到: File not found - "*.h": Invalid argument.

this question 的答案表明正确使用 shell-quote-argument 可能会解决此类问题,但我一直无法找到有效的解决方案。例如,这会产生相同的错误:

(format "find %s -type f -iname %s -or -iname %s | etags -"
   dir-name
   (shell-quote-argument "*.cpp")
   (shell-quote-argument "*.h"))

您正在尝试将 posix 语法与 Windows find 命令结合使用。这是错误的,原因有二:

  • 当然你不能希望它支持来自不同 OS 的语法。
  • Windows find 的行为类似于 grep,请改用 dir

希望对您有所帮助。

在评论中 sds 和 Daniele 的大力帮助下,我终于能够弄清楚问题所在。

我在做的事情有两个问题:

  1. 我使用的是带有 ms-dos 命令 shell 的 bash 解决方案。 DOS "find" 是一个与 Unix find 完全不同的命令,因此它抱怨其参数是完全有道理的。
  2. 常见的引用问题。我的 etags exe 的路径中有一个 space。我试着用 shell-quote-argument 来解决这个问题,但是在 MS-DOS shell 中所做的只是在参数周围加上转义引号。您仍然需要手动转义任何反斜杠,并且 DOS shell 需要其文件路径中的反斜杠。

感兴趣的朋友,Windows下的工作命令是:

(defun create-tags (dir-name)
  "Create tags file."
  (interactive "DDirectory: ")
  (shell-command
   (format "cd %s & dir /b /s *.h *.cpp | %s -"
       dir-name
       (shell-quote-argument "C:\Program Files\Emacs\emacs-25.0\bin\etags.exe"))))

唯一的怪癖是当 Emacs 提示您输入目录时,您必须确保给它一个 DOS shell 可以处理的目录。 ~/dirname 将不起作用。对于 emacs-fu 比我关心的人更擅长解决这个问题的人来说,可能有一个解决办法。