运行shell命令水晶语言并捕获输出

我习惯使用open3在Ruby中运行命令 . 因为似乎没有一个等效的lib在lang lang,我克服了这个:

def run_cmd(cmd, args)
      stdout_str = IO::Memory.new
      stderr_str = IO::Memory.new
      result = [] of Int32 | String
      status = Process.run(cmd, args: args, output: stdout_str, error: stderr_str)
      if status.success?
        result = [status.exit_code, "#{stdout_str}"]
      else
        result = [status.exit_code, "#{stderr_str}"]
      end
      stdout_str.close
      stderr_str.close
      result
    end

    cmd = "ping"
    hostname = "my_host"
    args = ["-c 2", "#{hostname}"]
    result = run_cmd(cmd, args)
    puts "ping: #{hostname}: Name or service not known" if result[0] != 0

有一个更好的方法吗?这位退休的网络专家说,他不是一名软件开发人员 .

提前感谢所有建议 .

回答(1)

2 years ago

可能是这样的:

def run_cmd(cmd, args)
  stdout = IO::Memory.new
  stderr = IO::Memory.new
  status = Process.run(cmd, args: args, output: stdout, error: stderr)
  if status.success?
    {status.exit_code, stdout.to_s}
  else
    {status.exit_code, stderr.to_s}
  end
end

我们不需要关闭 IO::Memory 因为它没有't represent a handle to any OS resources, just a block of memory, and we use tuples instead of arrays for the return. This means the callers know we'正好返回两个项目,第一个是数字,第二个是字符串 . 使用数组返回时,调用者只知道我们正在返回任意数量的项,其中任何一项都可以是int32或字符串 .

然后你可以像这样使用它:

cmd = "ping"
hostname = "my_host"
args = ["-c 2", hostname]
status, output = run_cmd(cmd, args)
puts "ping: #{hostname}: Name or service not known" unless status == 0