There's a lot to decide per use of startProcess, but here's an example:
import osproc, strutils, streams
let p = startProcess("perl", args = ["-ne", "$|=1; print; exit if $.>1"],
options = {poInteractive, poUsePath})
let (fromp, top) = (p.outputStream, p.inputStream)
top.write "repeat this please\n"
top.flush
echo fromp.readLine.toUpper
top.write "and this\n"
top.flush
echo fromp.readLine.toUpper
discard p.waitForExit
That starts a Perl process which echos what's written to it without buffering and exits after printing twice. The Nim then writes two strings, flushes them so they're definitely sent, reads them back, and prints them in upper case, one at a time.