vba - 从 VBA 同步运行 shell 命令,同时显示和捕获输出
问题描述
我想从我使用 rscript.exe 的 VBA 运行 R 脚本。我还传递了这个脚本 2 个参数。执行应同步运行,输出应实时显示并存储在日志文件中。
到目前为止,我能够创建一个命令,使用 cpearson shellAndwait 模块以同步方式从 VBA 运行它(VBA 在继续之前等待 shell 命令执行),并在一个漂亮的 cmd 提示窗口中实时获取输出。
batchCommand = Chr(34) & r_location & Chr(34) & _
" --verbose " & _
Chr(34) & fp_rscript & Chr(34) & _
" " & Chr(34) & arg1 & Chr(34) & _
" " & Chr(34) & arg2 & Chr(34)
errorcode = ShellAndWait (batchCommand, 0, vbMaximizedFocus, AbandonWait)
但是,如果我的 R 脚本失败,错误代码仍然为 0,并且获取输出的唯一方法是将 batchCommand 粘贴到 cmd 提示符中
添加 cmd /K 并将所有内容包装在第二组 " 中是没有选择的,因为 shellandwait 将等待用户手动关闭 cmd 提示符。
因此,我希望将输出写入一个文本文件,我使用 powershell & tee找到了这个解决方案。
但是,我使用 powershell 的新 batchCommand 失败了。
batchCommand = "powershell.exe " & _
Chr(34) & r_location & Chr(34) & _
" --verbose " & _
Chr(34) & fp_rscript & Chr(34) & _
" " & Chr(34) & fp_rscript & Chr(34) & _
" " & Chr(34) & arg2 & Chr(34) & _
" | tee " & Chr(34) & logfile & Chr(34)
批处理命令如下所示:
?batchCommand
powershell.exe "C:\Users\...\bin\RScript.exe" --verbose "E:\...\stage_2\antares_model_builder_stage_2.R" "E:\...\stage_2\antares_model_builder_stage_2.R" "E:\...\2018-09-28-1232 srv6_19-20_basecase" | tee "E:\...\2018-09-28-1232 srv6_19-20_basecase\s2_rscript_logfile.txt"
正如评论中所指出的,我不能再在 cmd 中输入这个 batchCommand,因为它试图解释 tee。
“'tee' 不是内部或外部命令、可运行程序或批处理文件。”
在 powershell 中粘贴命令给出:
致命错误:无法打开文件 'E:\SRV6\vanilla_hybrid\030':没有这样的文件或目录
所以它与路径中的空格有关。在 powershell.exe 之后添加“”围绕所有参数会产生相同的错误。但是,使用 '&' 有效:
& "C:\Users\hgd253\appdata\Local\Microsoft\AppV\Client\Integration\5A67571D-6F50-4EAD-BB33-A0D712D7FC6A\Root\R\R-3.3.3\bin\RScript.exe" --verbose "E:\SRV6\vanilla_hybrid\030 scripts\libraries\stage_2\antares_model_builder_stage_2.R" "E:\SRV6\vanilla_hybrid\030 scripts\libraries\stage_2\antares_model_builder_stage_2.R" "E:\SRV6\vanilla_hybrid\100 input buffer\2018-09-28-1337 srv6_19-20_basecase"
现在问题变成了如何将此字符串作为参数传递给 powershell -command?帮助文件指出
如果 Command 的值是字符串,则 Command 必须是 command 中的最后一个参数,因为在命令之后键入的任何字符都被解释为命令参数。
要编写运行 Windows PowerShell 命令的字符串,请使用以下格式:“& {}”,其中引号表示字符串,调用运算符 (&) 会导致执行命令。
所以我再试一次:
powershell -command "& {"C:\Users\hgd253\appdata\Local\Microsoft\AppV\Client\Integration\5A67571D-6F50-4EAD-BB33-A0D712D7FC6A\Root\R\R-3.3.3\bin\RScript.exe" --verbose "E:\SRV6\vanilla_hybrid\030 scripts\libraries\stage_2\antares_model_builder_stage_2.R" "E:\SRV6\vanilla_hybrid\030 scripts\libraries\stage_2\antares_model_builder_stage_2.R" "E:\SRV6\vanilla_hybrid\100 input buffer\2018-09-28-1337 srv6_19-20_basecase"}"
Fatal error: cannot open file 'E:\SRV6\vanilla_hybrid\030': No such file or directory
谁能帮我完成这个最终要求(将输出写入日志文件)工作?
解决方案
找到了解决方案。需要 ' 和 " 的混合物。批处理命令应如下所示:
?batchCommand
powershell.exe -command "& 'C:\Users\hgd253\appdata\Local\Microsoft\AppV\Client\Integration\5A67571D-6F50-4EAD-BB33-A0D712D7FC6A\Root\R\R-3.3.3\bin\RScript.exe' --verbose 'E:\SRV6\vanilla_hybrid\030 scripts\libraries\stage_2\antares_model_builder_stage_2.R' 'E:\SRV6\vanilla_hybrid\030 scripts\libraries\stage_2\antares_model_builder_stage_2.R' 'E:\SRV6\vanilla_hybrid\100 input buffer\2018-09-28-1337 srv6_19-20_basecase' | tee 'E:\SRV6\vanilla_hybrid\100 input buffer\2018-09-28-1337 srv6_19-20_basecase\s2_rscript_logfile.txt'"
VBA 代码因此变为:
batchCommand = "powershell.exe -command " & _
Chr(34) & "& " & _
Chr(39) & r_location & Chr(39) & _
" --verbose " & _
Chr(39) & fp_rscript & Chr(39) & _
" " & Chr(39) & fp_rscript & Chr(39) & _
" " & Chr(39) & arg2 & Chr(39) & _
" | tee " & _
Chr(39) & logfile & Chr(39) & Chr(34)
推荐阅读
- r - 如何将 array1 (2D) 添加到 array2 (3D)?
- sql - 具有仅包含另一列的部分功能的 SQL 查询?
- sql - 循环遍历表的列值
- java - 查看消息是否提到@here
- python-3.x - POSTMAN 是否支持 http2 请求
- git - .gitignore 不忽略和删除缓存不修复
- c# - 在创建要从 [FromBody] 接收某些字段的 Web 请求时如何指定
- node.js - 刷新猫鼬后默认生成的值(短网址)更改
- php - 根据仅保留最新的值删除数组中的重复对象(基于时间戳的第二个值)
- python - Selenium 用一个扭曲的 Python 滚动到视图中