我想提出以下一行:
emacs --eval '(ediff "$1" "$2")'
进入shell脚本,所以我不需要每次都写这个冗长而复杂的行。但是,当我把它放入我的shell脚本中时,我收到一个错误:
ediff-find-file: File `$1' does not exist or is not readable
我想这里存在某种"
转义问题,我需要在此行中添加一些\
。我究竟需要修复什么?
答案 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 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
}