emacs --eval'(ediff“$ 1”“$ 2”)'如何将这一行放入shell脚本?

时间:2012-01-13 10:07:28

标签: bash shell emacs

我想提出以下一行:

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

进入shell脚本,所以我不需要每次都写这个冗长而复杂的行。但是,当我把它放入我的shell脚本中时,我收到一个错误:

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

我想这里存在某种"转义问题,我需要在此行中添加一些\。我究竟需要修复什么?

3 个答案:

答案 0 :(得分:7)

这是正常的,您的字符串用单引号括起来,并且变量不会在单引号内展开。

您应该使用双引号,以便它们得到扩展,并转义字符串中的现有双引号:

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

值得注意的是,在扩展变量时,仅外部引号很重要。那就是:

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

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

答案 1 :(得分:5)

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

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

emacs --eval '(ediff command-line-args-left)' "$@"

如果有现有的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\")"

答案 2 :(得分:0)

有一个简单的功能称为" ediff"在我的$HOME/.profile中,我将两个提示结合在一起。来自Gilles abovedefunitive 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
}