2017-03-31 99 views
1

這看起來應該很簡單,但我拉出剩下的頭髮試圖讓它工作。在shell腳本中,我想運行一些定義字符串的Applescript代碼,然後將該字符串(包含單引號)傳遞給調用PHP的addslashes函數的shell命令,以便返回帶有單引號的字符串,並正確轉義。使用引號從Applescript調用shell命令

這是我到目前爲止的代碼 - 它返回一個語法錯誤。

STRING=$(osascript -- - <<'EOF' 
set s to "It's me" 
return "['test'=>'" & (do shell script "php -r 'echo addslashes(\"" & s & "\");") & "']" 
EOF) 
echo -e $STRING 

它應該返回此:

['test'=>'It\'s me'] 

回答

1

要以務實的解決方案補充Gordon Davisson's helpful answer

殼牌字符串不能包含\0(NUL)字符,但以下sed命令模仿其他逃避PHP的(名字古怪的)addslashes PHP function執行(\ -escaping '"\實例):

string=$(osascript <<'EOF' 
    set s to "It's me\\you and we got 3\" of rain." 
    return "['test'=>'" & (do shell script "sed 's/[\"\\\\'\\'']/\\\\&/g' <<<" & quoted form of s) & "']" 
EOF 
) 
printf '%s\n' "$string" 

產生

['test'=>'It\'s me\\you and we got 3\" of rain.'] 

請注意使用quoted form of,這對於從AppleScript將字符串傳遞到帶有適當引號的do shell script shell命令至關重要。

還要注意收盤在這裏-doc的分隔符,EOF怎麼樣,是其自己的行,以確保其正確識別(Bash中3.2.57,在Mac OS 10.12的使用,(也叫時爲/bin/sh,這是什麼do shell script做),這並不是絕對必要的,但Bash 4.x將正確地抱怨EOF)warning: here-document at line <n> delimited by end-of-file (wanted 'EOF')

2

首先,問這樣的問題時,請附上所發生的事情,你要不要什麼。當我嘗試,我得到:

42:99: execution error: sh: -c: line 0: unexpected EOF while looking for matchin 
sh: -c: line 1: syntax error: unexpected end of file (2) 

(實際上是兩個錯誤信息,其中一個部分覆蓋了其他。)那是你在說什麼?

如果是,問題是,你正在創建的內殼命令有報價的問題。看看試圖運行shell命令AppleScript的片段:

do shell script "php -r 'echo addslashes(\"" & s & "\");" 

由於s設置爲It's me,這種運行shell命令:

php -r 'echo addslashes("It's me"); 

其中有問題的撇號It's me作爲開始'echo ...的字符串的緊密引用。之後,me");中的雙引號被視爲打開一個新的帶引號的字符串,該字符串在「文件」結束之前沒有關閉,導致意外的EOF問題。

潛在的問題是,你試圖從AppleScript傳遞一個字符串到shell到PHP ......但是每個人都有自己的解析字符串的規則(關於如何引用和轉義工作的不同想法)。更糟糕的是,它看起來像你這樣做,所以你可以得到一個逃脫的字符串(遵循哪些逃脫規則?)傳遞給別的東西......這種方式就是瘋狂。

我不知道真正的目標是在這裏的,但必須有一個更好的辦法;一些不涉及與所有說不同語言的玩家的遊戲telephone。如果沒有,你幾乎註定了。

BTW,有腳本其他一些可疑的shell腳本的做法:

  • 不要使用全大寫的變量在shell腳本命名。有一大堆含有特殊含義的大寫變量,如果您不小心將其中的一個用於其他內容,可能會出現奇怪的結果。各地在腳本中的所有變量引用
  • 將雙引號,以避免他們得到分成多個「單詞」和/或擴展外殼通配符。例如,如果變量string被設定爲「[‘測試’=>‘這\’S-我']」,而你正好有一個名爲‘t’和在當前目錄下‘米’的文件,echo -e $string將打印「mt」,因爲這些是匹配[]模式的文件。
  • 請勿使用帶選項的echo和/或打印可能包含轉義字符的字符串,因爲不同的版本以不同方式處理這些事情。例如,某些版本將打印「-e」作爲輸出字符串的一部分。改爲使用printfprintf的第一個參數是一個格式字符串,它告訴它如何格式化所有其餘的參數。要以更可靠的形式效仿echo -e "$string",請使用printf '%b\n' "$string"
+0

感謝您的答覆!您的觀點是很好的關於shell腳本最佳實踐,我確實通常在生產工作中遵循這些指導方針,這只是我一起舉例說明問題的一個簡單例子。我是從這個版本的例子中得到的錯誤。我現在正在研究一種新方法,它將未修改的字符串從Applescript返回到父shell腳本 –