Как дождаться завершения процесса с использованием IO.popen?
Я использую IO.popen
в Ruby для запуска ряда команд командной строки в цикле. Затем мне нужно запустить другую команду за пределами цикла. Команда за пределами цикла не может работать до тех пор, пока все команды в цикле не будут завершены.
Как заставить программу ждать, пока это произойдет? В настоящий момент последняя команда запускается слишком быстро.
Пример:
for foo in bar
IO.popen(cmd_foo)
end
IO.popen(another_cmd)
Таким образом, все cmd_foos
должны возвращаться до запуска another_cmd
.
Ответы
Ответ 1
Я думаю, вам нужно будет назначить результаты из вызовов IO.popen
в цикле для переменных и продолжать называть read()
на них, пока eof()
не станет истинным для всех.
Затем вы знаете, что все программы завершили свое исполнение, и вы можете запустить another_cmd
.
Ответ 2
Используйте форму блока и прочитайте все содержимое:
IO.popen "cmd" do |io|
# 1 array
io.readlines
# alternative, 1 big String
io.read
# or, if you have to do something with the output
io.each do |line|
puts line
end
# if you just want to ignore the output, I'd do
io.each {||}
end
Если вы не читаете вывод, может быть, что процесс блокируется, потому что канал, соединяющий другой процесс и ваш процесс, заполнен, и никто не читает его.
Ответ 3
По-видимому, canonical way для этого:
Process.wait(popened_io.pid)
Ответ 4
for foo in bar
out = IO.popen(cmd_foo)
out.readlines
end
IO.popen(another_cmd)
Чтение вывода на переменную, а затем вызов out.readlines
сделал. Я думаю, что out.readlines
должен ждать завершения процесса до его возвращения.
Благодарим Эндрю Y за то, что указали мне в правильном направлении.
Ответ 5
Я предлагаю вам использовать Thread.join
для синхронизации последнего вызова popen
:
t = Thread.new do
for foo in bar
IO.popen(cmd_foo)
end
end
t.join
IO.popen(another_cmd)
Ответ 6
Вам нужен вывод popen
? Если нет, вы хотите использовать Kernel#system
или какую-либо другую команду?