使用引号从Applescript调用shell命令

时间:2017-03-31 21:00:37

标签: applescript

这似乎应该很简单,但是我要拔掉剩余的头发试图让它发挥作用。在shell脚本中,我想运行一些定义字符串的Applescript代码,然后将该字符串(包含单引号)传递给调用PHP的addslashes函数的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']

2 个答案:

答案 0 :(得分: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");中的双引号被视为打开一个新的引用字符串,该字符串在&#34;文件&#34;结束之前不会关闭,从而导致意外的EOF问题。

潜在的问题是你正在尝试将一个字符串从AppleScript传递到shell到php ......但是每个字符串都有自己的解析字符串的规则(对于如何引用和转义工作有不同的想法)。更糟糕的是,看起来你正在这样做,所以你可以得到一个转义字符串(跟随哪些转义规则?)传递给别的东西......这种方式就是疯狂。

我不确定这里的真正目标是什么,但必须有更好的方法;某些与telephone游戏不同的玩家都会说不同的语言。如果没有,那你就注定了。

顺便说一下,脚本中还有一些其他可疑的shell脚本实践:

  • 不要使用shell脚本中命名的all-caps变量。有一堆全部大写变量具有特殊含义,如果你不小心将其中一个用于别的东西,可能会发生奇怪的结果。
  • 在脚本中的所有变量引用周围加上双引号,以避免它们被分成多个&#34;单词&#34;和/或扩展为shell通配符。例如,如果变量string设置为&#34; [&#39; test&#39; =&gt;&#39;它&#39; s-me&#39;]&#34 ;,你碰巧有名为&#34; t&#34;和&#34; m&#34;在当前目录中,echo -e $string将打印&#34; m t&#34;因为那些是与[]模式匹配的文件。
  • 不要使用echo选项和/或打印可能包含转义符的字符串,因为不同的版本会以不同的方式处理这些内容。例如,某些版本将打印&#34; -e&#34;作为输出字符串的一部分。请改用printfprintf的第一个参数是一个格式字符串,告诉它如何格式化所有其余参数。要以更可靠的形式模仿echo -e "$string",请使用printf '%b\n' "$string"

答案 1 :(得分:1)

用实用的解决方案补充Gordon Davisson's helpful answer

Shell字符串不能包含\0(NUL)个字符,但是以下sed命令模拟PHP(奇怪命名)addslashes PHP function执行的所有其他转义({{1转义\'"个实例):

\

产量

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.'] 的使用,这对于通过正确引用将字符串从AppleScript传递到quoted form of shell命令至关重要。

还要注意关闭here-doc分隔符do shell script如何在其自己的行上以确保它被正确识别(在Bash 3.2.57中,在macOS 10.12上使用) ,(也称为EOF,这是/bin/sh所做的),这不是必须的,但Bash 4.x会正确地抱怨do shell script {{1} }}