Calling External Programs

I am writing a series of scripts that run and use output from a variety of network tools. What tools and what arguments will be determined at runtime, and these arguments can get complex. For example running nmap -PA -sV -O -T4 -p80,443,8080,8443,9000-10000 . If the target and arguments are know before running it, it is simple, either use `...` or %x{...}, but this method seems to not take string parameters only literals, using system makes it impossible to capture output which is what I need to do. I am using open3 which works but doesn't seem to be ideal. I would like to have to be free from constructing the complete command line string, but this is the only thing that seems to work.

If I try:inp,out,err = popen3(@tool, @args)inp.puts @targetinp.closeIt works with one argument, but not multiple. This would be perfect because I will likely have a list of targets, but arguments may change based on other runtime criteria. The problem is that this only works with 1 argument, passing in multiple arguments as either a single string or many arguments results in failure: either a broken pipe or nmap can't see the target. So my solution is to build a single string and pass that:

Where @tool is something like 'nmap -PA -sV -O -T4 -p80,443,8080,8443,9000-10000 '. Is there a better way to accomplish this? This works but having to build a lot strings during runtime is going to slow things down considerably as I may have hundreds of targets and a dozen or more tools to run and parse data from.