在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(...)
但剧本仍然破裂!
答案 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
命令的输出可以解析为数字 。echo $?
保证输出一个“看起来很数字”的字符串。)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
5
(Invalid 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
注意事项:
MacScript
仍会抛出错误;您可以使用它来区分语法错误和运行时错误。echo $?
之前的命令)没有使用\n
终止其输出,则解析退出代码将不起作用。