2012-01-13 97 views
3

我想提出以下行:

emacs --eval '(ediff "$1" "$2")' 

到一个shell脚本,所以我不需要写这个冗长而复杂的线条每次。然而,当我把它放到我的shell脚本,因为它是,我得到一个错误:

ediff-find-file: File `$1' does not exist or is not readable 

我想有某种"逃避问题,在这里,我需要把一些\在这条线。我需要解决什么问题?

回答

7

这是正常的,你的字符串被单引号包围,变量不会在单引号内扩展。

你应该在字符串中使用双引号,以便他们得到扩展,并逃避现有的双引号:

emacs --eval "(ediff \"$1\" \"$2\")" 

值得注意的是,扩大变量时,只外引号关系。即:

$ A=foo 
$ echo "'$A'" 

将打印'foo'。这里单引号包围$A的事实并不重要:外部引号是双引号。

5

您的直接问题是单引号会阻止shell的所有扩展。您需要双引号才能进行任何类型的扩展。但是,您不能只写emacs --eval "(ediff \"$1\" \"$2\")",因为Emacs的文件名不会正确引号,所以如果文件名包含"\,您的脚本就会中断。

幸运的是,有一个非常简单的解决方案:

emacs --eval '(ediff command-line-args-left)' "[email protected]" 

这将是更好地重用现有的Emacs的过程中,如果有一个,通过调用emacsclient。不幸的是,在Emacsclient中,--eval将其所有参数视为Lisp表达式。所以你需要在shell中进行引用。在bash或ksh中,可以使用${VARIABLE//PATTERN/REPLACEMENT}在双引号和反斜杠之前添加反斜杠;这有点痛苦,但它的工作。

quoted1=${1//\\/\\\\}; quoted1=${quoted1//\"/\\\"} 
quoted2=${2//\\/\\\\}; quoted2=${quoted2//\"/\\\"} 
emacsclient -a '' --eval "(ediff \"$quoted1\" \"$quoted2\")" 
+0

对于原因,我不知道,我需要更换其绝对路径的文件,以便ediff阅读。我添加了 file1 = $(readlink -f $ 1) file2 = $(readlink -f $ 2) and ediff load $ file1 and $ file2 – Lalylulelo 2017-09-20 12:27:38

0

为了有一个简单的功能在我$HOME/.profile称为“ediff”我两个小技巧结合在一起。一个从Gilles above和从defunitive blog。我添加了emacsclient和emacs作为备用编辑器-c说法:

ediff() { 
    if [ "X${2}" = "X" ] 
    then 
     echo "USAGE: ediff <FILE 1> <FILE 2>" 
    else 
     quoted1=${1//\\/\\\\};quoted1=${quoted1//\"/\\\"} 
     quoted2=${2//\\/\\\\};quoted2=${quoted2//\"/\\\"} 
     emacsclient -c -a emacs -e "(ediff \"$quoted1\" \"$quoted2\")" 
    fi 
} 
相关问题