2012-01-13 73 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 
} 
相關問題