Reputation: 47
I'm trying to pipe 2 IO object, i come from nodejs and we can do something like that:
const child_process = require('child_process')
const shell = child_process.spawn('/bin/sh')
shell.stdout.pipe(process.stdout)
shell.stdin.write('pwd\n')
shell.stdin.write('ls\n')
/* write all command i want */
and im looking for do the same thing in crystal
i know for the current example we can write
shell = Process.new("/bin/sh", input: Process::Redirect::Pipe, output: STDOUT, error: STDOUT)
shell.input << "ls\n"
shell.input << "pwd\n"
# all commands i want
but for some reason passing TCPSocket to Process.new input/output/error dont work very well (see here too if you have time Process and TCPSocket not close properly in crystal)
so im looking for an alternative way who will look like:
shell = Process.new("/bin/sh", input: Process::Redirect::Pipe, output: Process::Redirect::Pipe, Process::Redirect::Pipe)
shell.output.pipe(STDOUT) # not the crystal pipe but like the nodejs pipe
shell.input << "ls\n"
shell.input << "pwd\n"
# all commands i want
Upvotes: 1
Views: 345
Reputation: 4857
You can use IO.copy
inside a coroutine:
shell = Process.new("/bin/sh", input: :pipe, output: :pipe, error: :pipe)
spawn { IO.copy shell.output, STDOUT }
spawn { IO.copy shell.error, STDERR }
shell.input << "ls /\n"
shell.input << "pwd\n"
shell.wait
Upvotes: 3