Объединить стандартный вывод и стандартный вывод в Попене - PullRequest
3 голосов
/ 07 мая 2011

В Ruby's popen / spawn, как мне объединить STDOUT и STDERR в один поток без использования >2&1?

В Python это будет:

>>> import subprocess
>>> subprocess.check_output('my_prog args', stderr=subprocess.STDOUT, shell=True)

Обратите внимание на аргумент stderr.

Я использую Open3 - поскольку я не хочу просто stdout - но он уже разделяет их на два потока.

Ответы [ 2 ]

5 голосов
/ 07 мая 2011

Используя код из вашего другого вопроса , вы идете:

cmd = 'a_prog --arg ... --arg2 ...'
Open3.popen2({"MYVAR" => "a_value"}, "#{cmd}", {:err => [:child, :out]}) { |i,o|
  # This output should include stderr as well
  output = o.read()
  repr = "$ #{cmd}\n#{output}"
}

Пара изменений:

  1. Третий параметр на popen2 перенаправит stderr на stdoutl. Обратите внимание, что это должен быть стандартный вывод порожденного процесса, а не общесистемный стандартный вывод, поэтому вам нужно указать :child s :out
  2. Вам нужно использовать .popen2 вместо .popen3, так как кажется, что перенаправление игнорируется, если вы включите 3-й параметр e для stderr
  3. Поскольку вы используете .popen2, вы передаете |i,o| в блок:
1 голос
/ 19 июня 2015

Немного поздно, но взгляните на Open3.popen2e - документы .

Это ведет себя точно как popen3, но объединяет stderr stdout как второй аргументв блок.

Так что вы можете просто сделать

cmd = 'a_prog --arg ... --arg2 ...'
Open3.popen2e(cmd) { |input,output|
 # Process as desired, with output containing stdout and stderr
}
...