MacScript无效的过程调用或参数

MacScript无效的过程调用或参数

问题描述:

在OSX中,Excel提供了通过MacScript关键字运行Applescript代码的功能。我通过这个功能,运行shell代码,它一般是这样的:MacScript无效的过程调用或参数

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

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

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

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

The command exited with a non-zero status (number: 1)

所以我的问题是:我怎么陷阱MacScript返回代码,并防止Excel打破?我尝试过:

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

但脚本仍然打破!

通常,为了防止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命令的输出可以解析为数字
    (上述命令是安全的,因为上述命令的标准输出是在文件中捕获的,因此后续的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)。

最后,您可以结合 2层的方法 - 返回命令的输出其特定的退出代码:

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的输出,则解析出退出代码将不起作用。
+0

哇。谢谢你的清晰和细节。超过我的预期:) +1 – ekkis 2015-03-31 23:32:45

+0

@ekkis:我的荣幸。我自己学到了一两件事。 – mklement0 2015-04-01 01:24:09