emacs lisp shell进程参数存在问题

emacs lisp shell进程参数存在问题,emacs,lisp,perforce,elisp,Emacs,Lisp,Perforce,Elisp,我正试图直接从xemacs运行P4V命令。 将p4.el拉入emacs后,我编写了以下内容: (defun p4v-command (cmd) (get-buffer-create p4-output-buffer-name);; We do these two lines (kill-buffer p4-output-buffer-name) ;; to ensure no duplicates (call-process "p4v" nil (get-buffer-cr

我正试图直接从xemacs运行P4V命令。 将p4.el拉入emacs后,我编写了以下内容:

(defun p4v-command (cmd)
  (get-buffer-create p4-output-buffer-name);; We do these two lines
  (kill-buffer p4-output-buffer-name)      ;; to ensure no duplicates
  (call-process "p4v" nil (get-buffer-create p4-output-buffer-name) nil
                "-p" (p4-get-p4-port)
                "-u" "UserName"
                "-c" (p4-current-client)
                "-cmd" (shell-quote-argument (concat cmd " " (buffer-name))))
  (display-buffer p4-output-buffer-name))
(shell-quote-argument "prevdiff file.txt")
"prevdiff\\ file.txt"
我正在尝试获取以下for shell命令(当cmd等于prevdiff时):

然而,当我使用prevdiff执行上述函数时,我得到以下错误

P4V: unrecognized argument '"prevdiff' for '-cmd' option.
因此,调用过程似乎正在将带引号的字符串“prevdiff file.txt”拆分为各个参数,而P4V只处理第一个参数

这似乎不会发生在我用callprocess尝试过的其他命令上,所以我不确定这是lisp问题还是与P4V有关


有人知道如何解决这个问题吗?

调用过程肯定不会连接其参数;它直接将它们传递给程序。要查看这种情况,请键入M-:并计算以下表达式:

(call-process "/bin/ls" nil "*scratch*" nil "avg ba")
其中“avg”和“ba”是当前目录中的文件。我将以下消息插入我的暂存缓冲区:

如果调用进程重新解析了参数,它会将“avgba”拆分为两个独立的参数——但错误消息显示它没有

相反,问题在于shell quote参数。当我评估您在scratch缓冲区中提到的调用时,我得到以下结果:

(defun p4v-command (cmd)
  (get-buffer-create p4-output-buffer-name);; We do these two lines
  (kill-buffer p4-output-buffer-name)      ;; to ensure no duplicates
  (call-process "p4v" nil (get-buffer-create p4-output-buffer-name) nil
                "-p" (p4-get-p4-port)
                "-u" "UserName"
                "-c" (p4-current-client)
                "-cmd" (shell-quote-argument (concat cmd " " (buffer-name))))
  (display-buffer p4-output-buffer-name))
(shell-quote-argument "prevdiff file.txt")
"prevdiff\\ file.txt"
换句话说,p4v实际接收的命令就是您在shell中输入的命令:

p4v -p port -u user -c client -cmd '"prevdiff file.txt"'
这就是p4v抱怨“prevdiff”的原因

所以我认为你想要的是:

"-cmd" (concat cmd " " (shell-quote-argument (buffer-name))))

(当然,请检查我的参数)。

我无法准确再现您看到的内容,但您确定需要
(shell quote参数…)
在那里?似乎
调用进程
将参数直接传递给进程,而不使用外壳。如果不尝试引用参数会发生什么?谢谢Mike。我想我确实需要它。它将引号插入字符串中,这样您就可以得到一个带有“\”prevdiff file.txt\”的字符串“。这意味着在传递给shell命令时,字符串被括在引号中。这不太正确:当您获取
“prevdiff\\file.text”
并将其传递给
调用进程时,引号不会被发送到进程(它们是elisp字符串语法的一部分,而不是字符串的一部分)。我想现在发生的是@Jim Blandy和我在unixy系统上,而@Jeremy Simon在Windows上,
shell quote argument
将返回
“\”prevdiff file.txt\”
。这可以解释p4v的错误。是的,迈克,你说得对。我误读了划痕缓冲区中的内容。杰里米,我很高兴我的错误和操作系统的差异被抵消了!来自Emacs Lisp手册:;;此示例显示MS-DOS和MS Windows上的行为。(shell引号参数“foo>bar”)=>“\“foo>bar\”,还有额外的引号。