2010-07-29 18 views
4

Je tente d'exécuter des commandes P4V directement à partir de xemacs. Après avoir tiré dans le p4.el à emacs j'ai écrit ce qui suit:Problème avec les arguments du processus de shell Lisp 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)) 

Je suis en train d'obtenir ce qui suit pour commande shell (lorsque cmd est égal à prevdiff):

p4v -p port -u user -c client -cmd "prevdiff file.txt" 

Cependant , quand j'exécute la fonction ci-dessus avec prevdiff je reçois l'erreur suivante

P4V: unrecognized argument '"prevdiff' for '-cmd' option. 

il semble donc que le processus d'appel est le fractionnement de la chaîne entre guillemets « prevdiff fichier.txt » dans dans arguments individuels et P4V ne traite que le premier.

Cela ne semble pas se produire pour d'autres commandes que j'ai essayées avec le processus d'appel, donc je ne suis pas sûr si c'est un problème de lisp ou quelque chose à voir avec P4V.

Est-ce que quelqu'un sait comment résoudre ce problème?

+0

Je ne peux pas reproduire ce que vous voyez exactement, mais êtes-vous sûr d'avoir besoin de l'argument '(shell-quote-argument ...)'? Il semble que 'call-process' passe les arguments directement au processus, sans uinsg le shell. Que se passe-t-il si vous n'essayez pas de citer l'argument? –

+0

Merci Mike. Je pense que j'en ai besoin. Il insère les guillemets dans la chaîne afin que vous obteniez une chaîne avec "\" prevdiff file.txt \ "". Cela signifie que la chaîne est placée entre guillemets lorsqu'elle est passée à la commande shell. – sickgemini

Répondre

4

call-process ne concatène définitivement pas ses arguments; il les transmet directement au programme. Pour voir c'est le cas, le type M-: et évaluer l'expression suivante:

(call-process "/bin/ls" nil "*scratch*" nil "avg ba") 

où « avg » et « ba ​​» sont des fichiers dans le répertoire courant. Je reçois le message suivant inséré dans mon scratch tampon:

/bin/ls: cannot access avg ba: No such file or directory 

Si appel processus a analysait à nouveau les arguments, il aurait divisé « Avg ba » en deux arguments distincts --- mais le message d'erreur montre que non. Au lieu de cela, le problème est avec l'argument shell-quote-argument. Quand j'évalue l'appel que vous mentionnez dans le gratter tampon, je reçois le texte suivant:

(shell-quote-argument "prevdiff file.txt") 
"prevdiff\\ file.txt" 

En d'autres termes, la commande P4V reçoit est ce que vous fait entrer dans la coquille comme:

p4v -p port -u user -c client -cmd '"prevdiff file.txt"' 

Ce pourquoi P4V se plaint de « prevdiff

donc ce que je pense que vous voulez à la place:.

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

(mais vérifiez mes parens, bien sûr).

+0

Merci Jim! A travaillé un régal. – sickgemini

+0

Ce n'est pas tout à fait correct: quand vous obtenez '' prevdiff \\ file.text "' et que vous passez ensuite 'call-process', les guillemets ne sont pas envoyés au processus (ils font partie de la chaîne elisp syntaxe, ne faisant pas partie de la chaîne).Je pense que ce qui se passe est que @Jim Blandy et moi sommes sur les systèmes unixy alors que @Jeremy Simon est sur Windows, où 'shell-quote-argument' retournera' "\" prevdiff file.txt \ "" '. Cela expliquerait l'erreur 'p4v'. –

+0

Oui, Mike, tu as raison. J'ai mal lu ce qui était dans le tampon * scratch *. Jeremy, je suis content que mon erreur et la différence d'OS soient annulées! –