TOPIC: new RunPiped
#863
new RunPiped 3 Years, 3 Months ago
Sometimes you want to run an external program and feed it's standard input and read it's standard output. You can do this by using System and redirecting the input and output to/from files but this is not ideal. And System usually displays a "dos" window while it's running which does not look good to users (and can lead to problems if they close the dos windows).

At first I thought I could just add a built-in function that would call popen. But according to MSDN (and other web sources) popen does not work from GUI programs. They point you to Creating a Child Process with Redirected Input and Output. (I'm not sure why they couldn't just fix popen, since their own example shows it's possible.)

Using this example, it was easy to add a built-in class to run a program with the input and output connected to pipes. For example:

Code:


rp = RunPiped("dir"')
while false isnt s = rp.Read()
Print(s)
rp.Close()



or this example using the GnuWin32 command line editor "ed":

Code:


rp = RunPiped("ed")
rp.Write("an")
rp.Write("hello worldn")
rp.Write(".n")
rp.Write("1,$pn")
rp.Write("Qn")
while false isnt s = rp.Read()
Print(s)
rp.Close()



I called it "RunPiped" for now, but maybe it should be called "Popen"?

One of the things we want to use this for is to run #sh3ll to transfer files to/from Amazon S3.

Post edited by: andrew, at: 2007/05/03 21:35
 
 
andrew
 
#865
Re:new RunPiped 3 Years, 3 Months ago
Very nice. :)

I like the 'RunPiped' name... I think it's easier to remember. ;)
 
 
Mauro
 
#870
Re:new RunPiped 3 Years, 3 Months ago
I realized I forgot to implement the block version of RunPiped (similar to File) which handles calling Close (even if there is an exception).

With this addition, the examples can also be written as:

Code:


RunPiped("dir")
    { |rp|
    while false isnt s = rp.Read()
        Print(s)
    }

RunPiped("ed")
    { |rp|
    rp.Write("an")
    rp.Write("hello worldn")
    rp.Write(".n")
    rp.Write("Qn")
    while false isnt s = rp.Read()
        Print(s)
    }



Post edited by: andrew, at: 2007/05/03 21:36
 
 
andrew