How to Wait for Process to Finish Using Io.Popen

How to wait for process to finish using IO.popen?

I think you'd need to assign the results from the IO.popen calls within the cycle to the variables, and keep calling read() on them until eof() becomes true on all.

Then you know that all the programs have finished their execution and you can start another_cmd.

io.popen - how to wait for process to finish in Lua?

If you are using standard Lua your code looks a bit odd. I am not completely sure about io.popen semantics regarding timeouts or platform dependencies, but the following works at least on my machine.

local file = assert(io.popen('/bin/ls -la', 'r'))
local output = file:read('*all')
file:close()
print(output) -- > Prints the output of the command.

wait process until all subprocess finish?

A Popen object has a .wait() method exactly defined for this: to wait for the completion of a given subprocess (and, besides, for retuning its exit status).

If you use this method, you'll prevent that the process zombies are lying around for too long.

(Alternatively, you can use subprocess.call() or subprocess.check_call() for calling and waiting. If you don't need IO with the process, that might be enough. But probably this is not an option, because your if the two subprocesses seem to be supposed to run in parallel, which they won't with (call()/check_call().)

If you have several subprocesses to wait for, you can do

exit_codes = [p.wait() for p in p1, p2]

(or maybe exit_codes = [p.wait() for p in (p1, p2)] for syntactical reasons)

which returns as soon as all subprocesses have finished. You then have a list of return codes which you maybe can evaluate.

Infinity loop in io.popen function in lua

I don't know what the iw command does, but using a pipe without reading anything from it and closing it immediately after opening it opens the possibility that the program never executes.

I suggest using os.execute instead of io.popen:

while true do
print("Hi")
os.execute("iw wlan0 scan; iw wlan0 disconnect; iw wlan0 connect Name")
print("Goes to Scan")
end

How do I display the popen output as it happens through a get request?

IO::popen:

Runs the specified command as a subprocess; the subprocess’s standard
input and output will be connected to the returned IO object.

stdout is a file. You are telling ruby to read the whole file with the line io.read, therefore ruby has to wait until the end of file is reached to return the text, which happens when the other end closes the pipe, i.e. when the target program has finished executing. You don't have to read a file a whole file at a time, instead you can read a file line by line:

def process(command)
IO.popen(command) do |io|
io.each do |line|
puts line
end
end
end

That tells ruby to read the file until it finds a newline, then return the text...over and over gain until the end of file is reached.

Here's a full example:

#my_prog.rb

text = ""

1.upto(10) do
text << "."

puts text
STDOUT.flush

sleep 1
end

...

def process(command)
IO.popen(command) do |io|
io.each do |line|
puts line
end
end
end

my_command = 'ruby ./my_prog.rb'
process(my_command)

Note that unless the target program flushes the output, the output will be buffered, and therefore the text won't be available to be read until the buffer is filled (at which point the buffer will be flushed automatically) or the target program ends(at which point the buffer also will be flushed automatically). Instead of calling STDOUT.flush() repeatedly, you can just use the line STDOUT.sync = true at the top of your program. When sync is set to true, ruby won't buffer the output.

Stopping IO.popen in the middle of execution using Exceptions given a bad condition

So - disclaimer, I am using Ruby 1.8.6 and on Windows. It is the only Ruby that the software I use currently supports, so there may be a more elegant solution. Overall, it came down to making sure the process died using the Process.kill command before continuing execution.

IO.popen(cmdLineExecution) do |stream|
stream.each do |line|
puts line
begin
#if it finds an error, throws an exception
analyzeLine(line)
rescue correctionException
#if it was able to handle the error
puts "Handled the exception successfully"
Process.kill("KILL", stream.pid) #stop the system process
rescue correctionFailedException => failedEx
#not able to handle the error
puts "Failed handling the exception"
Process.kill("KILL", stream.pid) #stop the system process
raise "Was unable to make a known correction to the running enviorment: #{failedEx.message}"
end
end
end

I made both the exceptions standard classes that inherit Exception.

Lua best practice close variable with popen()

Lua will close the file handle automatically when the garbage collector gets around to collecting it.

Lua Manual 5.4: file:close

Closes file. Note that files are automatically closed when their handles are garbage collected, but that takes an unpredictable amount of time to happen.

BUT, it is best practice to close the handles yourself as soon as you are done with the handle, this is because it will take an unknown amount of time for the GC to do it.

This is not an issue of memory but of a much more limited resource of open file handles, something like 512 on a windows machine, a small pool for all the applications running on it.


As for the second question, when you reassign a variable AND there are no other remaining references to the previous value, that value will eventually be collected by the GC.

Using io.popen effectively, or alternative solutions to it

There are various external libraries to let you do this for you.

Check out winapi, apr or ex



Related Topics



Leave a reply



Submit