MacScript无效的过程调用或参数

时间:2015-03-31 18:10:22

标签: macos excel-vba applescript vba excel

在OSX Excel中,提供了通过MacScript关键字运行Applescript代码的功能。我正在通过此功能运行shell代码,它通常如下所示:

MacScript "do shell script ""/usr/bin/whatever"""

最近我决定要捕获输出(和stderr),因为命令失败了,我想看看错误是什么......所以我重写了这样:

MacScript "do shell script ""/usr/bin/whatever > /tmp/out 2>&1"""

但是我得到了上面的错误。如果我在AppleScript编辑器中运行给定的命令,我会收到错误:

  

该命令以非零状态退出(编号:1)

所以我的问题是:如何捕获MacScript的返回码并防止Excel崩溃?我试过了:

Dim rc As Integer: rc = MacScript(...)

但剧本仍然破裂!

1 个答案:

答案 0 :(得分:2)

通常,为防止do shell script(因此,间接地,MacScript())抛出错误,请确保shell命令以代码0退出。

在您的情况下,要仅捕获shell命令的退出代码,请将; echo $?附加到传递给do shell script的命令字符串中:

简化示例,使用格式错误的date命令:

Dim rc As Integer
rc = MacScript("do shell script ""date -nosuchoptions; echo $?""") ' returns 1
  • echo $?将(前面)命令的退出代码输出到 stdout ,因此由do shell script
  • 返回
  • 作为 - 理想的 - 副作用,退出代码将设置为0,因为echo命令成功;因此,整个命令以代码0退出,从而阻止do shell script抛出错误。

警告

  • 由于您要将MacScript的返回值分配给Integer变量,请确保do shell script命令的输出可以解析为数字
    (上面的命令是安全的,因为前面的命令的stdout输出是在文件中捕获的,因为前面的命令的stdout输出被保存在文件中,后续的echo $?保证输出一个“看起来很数字”的字符串。)
  • 如果你的shell命令语法不正确,MacScript仍会抛出错误;您可以使用它来区分语法错误和运行时错误。

相比之下,如果你仍然想要返回一个命令的输出而只是简单地知道抽象中的是否出错:

    Dim stdout As String
    On Error Resume Next  ' ignore runtime errors
    stdout = MacScript("do shell script ""date -nosuchoptions""")
    If Err.Number <> 0 Then
      MsgBox "Something went wrong.", vbExclamation
    Else
      MsgBox "Captured output: " & stdout, vbInformation
    End If
  • 请注意,此方法允许您确定shell命令的特定退出代码,因为Excel VBA会转换任何非零shell退出代码进入通用错误号5Invalid procedure call or argument)。

最后,您可以合并这两种方法 - 返回命令的输出其特定的退出代码:

    Dim stdout As String, rc As Integer, pos As Integer
    ' Execute the command, and appends its exit code as the *last line* of output.
    ' Note how both stdout and stderr output are captured via `2>&1`.
    stdout = MacScript("do shell script ""{ date; date -nosuchoptions; } 2>&1; echo $?""")
    ' Extract the last line from the output captured.
    pos = InStrRev(stdout, Chr$(13)) ' find last line break (\n has been translated to \r by `do shell script`)
    rc = Mid(stdout, pos + 1)        # exit code
    stdout = Left(stdout, pos - 1)   # captured output (only)
    If rc <> 0 Then
      MsgBox "Command failed with exit code " & rc & "; captured output: " & stdout, vbExclamation
    Else
        MsgBox "Captured output: " & stdout, vbInformation
    End If

注意事项

  • 如果你的shell命令语法不正确,MacScript仍会抛出错误;您可以使用它来区分语法错误和运行时错误。
  • 如果您的shell命令(echo $?之前的命令)没有使用\n终止其输出,则解析退出代码将不起作用。