【问题标题】:Calling a shell command from Applescript with quotes使用引号从 Applescript 调用 shell 命令
【发布时间】:2017-03-31 21:00:36
【问题描述】:

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

【问题讨论】:

    标签: applescript


    【解决方案1】:

    首先,当提出这样的问题时,请说明正在发生的事情,而不仅仅是您想要做的事情。当我尝试这个时,我得到:

    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 sn-p:

    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 的游戏,玩家都说不同的语言。如果没有,那你就完蛋了。

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

    • 不要使用在 shell 脚本中命名的全大写变量。有一堆全大写变量具有特殊含义,如果您不小心将其中一个用于其他用途,可能会出现奇怪的结果。
    • 将双引号括住脚本中的所有变量引用,以避免它们被拆分为多个“单词”和/或扩展为 shell 通配符。例如,如果变量string被设置为“['test'=>'It\'s-me']”,而你恰好在当前目录下有名为“t”和“m”的文件,@ 987654331@ 将打印“m t”,因为这些文件与 [] 模式匹配。
    • 不要将echo 与选项一起使用和/或打印可能包含转义的字符串,因为不同的版本对这些内容的处理方式不同。例如,某些版本将打印“-e”作为输出字符串的一部分。请改用printfprintf 的第一个参数是一个格式字符串,它告诉它如何格式化所有其余参数。要以更可靠的形式模拟 echo -e "$string",请使用 printf '%b\n' "$string"

    【讨论】:

    • 感谢您的回复!关于 shell 脚本最佳实践,您的观点得到了很好的认可,而且我确实通常在生产工作中遵循这些准则。这只是我为了说明问题而拼凑的一个简单示例。是的,这些是我从这个版本的示例中得到的错误。我现在正在研究一种新方法,将未经修改的字符串从 Applescript 返回到父 shell 脚本
    【解决方案2】:

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

    Shell 字符串不能包含 \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 命令至关重要。

    还要注意结束 here-doc 分隔符 EOF 如何位于其自己的行上以确保正确识别它(在 Bash 3.2.57 中,在 macOS 10.12 上使用,(同样当被称为/bin/sh 时,这就是do shell script 所做的),这并不是绝对必要的,但是Bash 4.x 会正确地抱怨EOF)warning: here-document at line &lt;n&gt; delimited by end-of-file (wanted 'EOF')

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-01-22
      • 1970-01-01
      • 2016-04-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-03-02
      • 1970-01-01
      相关资源
      最近更新 更多