I'd figured out the Open3.popen3 stuff pretty well. The problem is in the stdout/stderr pipes. I don't know exactly how it all works, but if you write a program that does something like this...
It opens the 'zmprov' command line and then sends the sm/gaf/sm commands through to zmprov. It all works (sort of) if all you ever want to read is from stdout....but if you want to read stderr too (like I send a bogus account name to that second sm)...you can't. Because of the fact that the program never closes the zmprov command....the stdout/stderr pipes never close and send an EOF (or whatever it's called) to the program so it never knows when to stop reading from the pipe and just sticks in an infinite loop.
stdin, stdout, stderr = Open3.popen3("zmprov")
stdout.each do |line|
stderr.each do |line|
Anyway...too much info probably....but I haven't been able to get it to work that way yet. So what I've done is start zmprov with 'zmprov 2>&1' which sends stderr through stdout. So now I only have to keep track of one pipe. I still sometimes get stuck and have to figure out a way to get out of it...either by checking for something in the pipe and when I find it exit the loop. Some commands though return nothing if they are successful....so I actually have to send a bogus command in just behind it so I have something to match against. An example is 'mfg' (modifyFolderGrant)....if it succeeds then it just comes back to the prompt and there is nothing in stdout to check for so I just send the word "bogus" in to the prompt...
...and it gives me an error in stdout that I can match against and drop out of the loop.
Anyway...my method of doing it works...though it's a little clunky.
Eventually when I get this all coded I'll maybe drop it into my page on the Zimbra wiki so anyone else interested in doing this with Ruby can not have to go through the headache I have. Maybe find a better way of doing things too...I'm certainly not the worlds greatest Ruby coder.