我试图通过Ruby运行一系列命令,并捕获stdin、stdout、stderr和exitstatus。
require "open3"
require "pp"
command_list = [
"export MY_ENV_VAR=foobar",
"printenv MY_ENV_VAR"
]
executed_commands = []
result = nil
command_list.each do |command|
stdout, stderr, status = Open3.capture3(command)
result = status.exitstatus
executed_commands << [command, stdout, stderr, result]
break if result != 0
end
pp executed_commands
puts "exited with #{result} exit status."此进程以非零状态退出,指示printenv MY_ENV_VAR命令失败,且命令不在同一进程中运行。
如何在单个shell进程中执行一系列命令,记录stdin**,** stdout**,** stderr 以及每个命令的退出状态?
发布于 2017-06-15 22:35:19
我强烈建议您不要将多个shell命令链接到一个单独的系统调用中,如果您不必这样做的话。一个主要的警告是,您不能单独检查链中每个命令的返回代码。这导致对命令流缺乏控制。例如,如果链中的第一个命令因任何原因而失败,则无论第一个命令的状态如何,后续命令仍将尝试执行。这可能是不可取的。
我建议将popen功能封装到一个方法中,只需为要运行的每个命令调用该方法即可。这将允许您在命令逐条执行的基础上对任何失败的执行作出反应。
发布于 2017-06-15 20:46:57
运行一系列命令的代码很好。问题是您设置的环境变量不正确。子进程不能像您尝试的那样设置其父进程的环境。子进程确实继承了其父进程的环境,因此这里有一种修复代码的方法:
require "open3"
require "pp"
ENV['MY_ENV_VAR'] = 'hi'
command_list = [
"printenv MY_ENV_VAR"
]
executed_commands = []
result = nil
command_list.each do |command|
stdout, stderr, status = Open3.capture3(command)
result = status.exitstatus
executed_commands << [command, stdout, stderr, result]
break if result != 0
end
pp executed_commands
puts "exited with #{result} exit status."当我在Linux上使用Ruby2.3.1运行这个程序时,结果是:
[["printenv MY_ENV_VAR", "hi\n", "", 0]]
exited with 0 exit status.现在,如果您想在不修改您自己流程的环境的情况下将一个环境变量传递给子进程,请参阅Open3.capture3参数的文档
https://ruby-doc.org/stdlib/libdoc/open3/rdoc/Open3.html#method-c-capture3
https://stackoverflow.com/questions/44576683
复制相似问题