在 capture3 中运行 shell 命令时抑制命令提示符输出

时间:2021-03-08 20:39:45

标签: ruby windows command-prompt popen3

我正在通过 capture3 在 Ruby 脚本中运行 Amazon's Kindle Previewer 工具。 Kindle Previewer 命令验证 epub 文件并将日志打印到指定文件夹,同时还在终端运行时打印日志。不过,我希望这些消息中的任何一条出现在终端中。命令本身的语法是 kindlepreviewer [epub file] -log -output [log output folder]。在我的 capture3 语句中,它看起来像这样:

stdout, stderr, status = Open3.capture3("kindlepreviewer #{epub_file} -log -output #{output_folder}")

这可以在 Mac 和 PC 上成功执行,而且我可以在脚本的其他地方使用输出。在 Mac 上,终端窗口会抑制命令运行时生成的输出,这正是我想要的。我的问题是在 Windows 中,所有输出仍然在命令提示符中通过。我不知道如何关闭它。基于类似的问题,例如:Suppressing the output of a command run using 'system' method while running it in a ruby script,我尝试了类似的东西:

stdout, stderr, status = Open3.capture3("#{cmd} #{epub} -log -output #{@kindle_folder} > /dev/null 2>&1")

这根本没有影响。正常执行,所有输出仍然出现在命令提示符中。

我知道 Kindle Previewer 是一个非常具体的工具,可以在这里引用,但我似乎找不到更一般的答案,为什么在 Mac 上运行 capture3 命令会抑制终端中的输出,但在终端中运行它Windows 命令提示符不会。我应该在 PC 上用 Ruby 运行 shell 命令,同时仍然能够将命令的输出存储在脚本中吗?

1 个答案:

答案 0 :(得分:0)

我自己也遇到了类似的问题,我想完全阻止 Windows 上的任何控制台输出。请记住,Windows DOS 提示符不是 Bash shell,因此您确实不能使用相同的输出重定向语法。

在尝试了几个不同的选项后,我最终使用了 win32/process,它可以直接访问 Win32 API CreateProcess 方法。只有使用这种方法才能完全防止输出:

require 'win32/process'

pinfo = Process.create({ command_line:   "program arguments",
                         creation_flags: Process::DETACHED_PROCESS })

# Taken from the win32/process manual, in case you need to wait for the
# spawned process to finish before continuing with the rest of your script:
sleep 0.1 while !Process.get_exitcode(pinfo.process_id)

DETACHED_PROCESS 这里是关键,因为它可以防止创建的进程访问原始终端。

使用 gem install win32-process 安装此 gem。

相关问题