How to open interactive terminal apps with child_process?

1,653 views
Skip to first unread message

James Coglan

unread,
Sep 21, 2012, 6:40:14 AM9/21/12
to Node list
Hi all,

I'd like to have my command-line Node program invoke another interactive shell program (in this case w3m, but think vim, less, and so on) as a child process so that it appears in my terminal. I thought I could do that like this:

require('child_process').execFile('w3m', ['http://www.google.com'], {stdio: 'inherit'})

But it turns out that doesn't work. Is this possible?

--
James Coglan
http://jcoglan.com
+44 (0) 7771512510






James Coglan

unread,
Sep 21, 2012, 7:03:08 AM9/21/12
to Node list
On 21 September 2012 12:40, James Coglan <jco...@gmail.com> wrote:
I'd like to have my command-line Node program invoke another interactive shell program (in this case w3m, but think vim, less, and so on) as a child process so that it appears in my terminal. I thought I could do that like this:

require('child_process').execFile('w3m', ['http://www.google.com'], {stdio: 'inherit'})

But it turns out that doesn't work. Is this possible?

This is a bit better in that it displays the output from w3m, but it's not color formatted (I guess because its stdin is not a tty) and I can't interact with it properly:

var cp  = require('child_process'),
    w3m = cp.execFile('w3m', ['http://www.google.com']);

process.stdin.pipe(w3m.stdin);
w3m.stdout.pipe(process.stdout);

So I need to make w3m know it's writing to a tty, and forward every keystroke from Node to the child process. I tried process.stdin.setRawMode(true) but this just locked the process up and CTRL-C and CTRL-Z did not work. 

Ben Noordhuis

unread,
Sep 21, 2012, 9:11:35 AM9/21/12
to nod...@googlegroups.com
On Fri, Sep 21, 2012 at 12:40 PM, James Coglan <jco...@gmail.com> wrote:
> Hi all,
>
> I'd like to have my command-line Node program invoke another interactive
> shell program (in this case w3m, but think vim, less, and so on) as a child
> process so that it appears in my terminal. I thought I could do that like
> this:
>
> require('child_process').execFile('w3m', ['http://www.google.com'], {stdio:
> 'inherit'})
>
> But it turns out that doesn't work. Is this possible?

Yes, but not with the child_process module (not reliably anyway). Try
https://github.com/chjj/pty.js

Mark Hahn

unread,
Sep 21, 2012, 2:07:56 PM9/21/12
to nod...@googlegroups.com
It amazes me how often a question about some capability of node is answered with one or more spot-on solutions.  I guess lampp can offer the same convenience but node is only a few years old.


--
Job Board: http://jobs.nodejs.org/
Posting guidelines: https://github.com/joyent/node/wiki/Mailing-List-Posting-Guidelines
You received this message because you are subscribed to the Google
Groups "nodejs" group.
To post to this group, send email to nod...@googlegroups.com
To unsubscribe from this group, send email to
nodejs+un...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/nodejs?hl=en?hl=en

James Coglan

unread,
Sep 21, 2012, 5:22:00 PM9/21/12
to Node list
On 21 September 2012 12:40, James Coglan <jco...@gmail.com> wrote:
I'd like to have my command-line Node program invoke another interactive shell program (in this case w3m, but think vim, less, and so on) as a child process so that it appears in my terminal. I thought I could do that like this:

require('child_process').execFile('w3m', ['http://www.google.com'], {stdio: 'inherit'})

Turns out I can do what I want using spawn() instead of execFile(). I don't quite understand why from the docs -- someone care to enlighten me as to what's going on with processes and I/O streams and what the difference is between the two functions?

Tim Caswell

unread,
Sep 21, 2012, 6:09:44 PM9/21/12
to nod...@googlegroups.com
execFile is for buffering the output and storing it in a single value
in the callback. spawn is for streaming the results. My guess is
execFile ignores the custom stdio pipes.
Reply all
Reply to author
Forward
0 new messages