2017-03-31 72 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脚本 –