1

I'm working on a small cli tool that can automatically deploy Google Home actions based on the projects that are setup in a directory.

Basically my script checks the directories and then asks which project to deploy. The actual command that should run is coming from Google's cli gactions

To run it with arguments I setup a spawned process in my node-script:

const { spawn } = require('child_process')
const child = spawn('./gactions', [
    'update',
    '--action-package',
    '<PATH-TO-PACKAGE>',
    '--project',
    '<PROJECT-NAME>'
])

child.stdout.on('data', data => {
    console.log(data)
}

However, the first time a project is deployed, the gactions cli will prompt for an authorization code. Running the code above, I can actually see the prompt, but the script won't proceed when actually entering that code.

I guess there must be some way in the child process to capture that input? Or isn't this possible at all?

mihai
  • 37,072
  • 9
  • 60
  • 86
Maarten
  • 635
  • 2
  • 8
  • 22
  • The child process's `stdin`, `stdout`, and `stderr` are streams, so you can manipulate them as you like. The node documentation gives you a very simple [example](https://nodejs.org/api/child_process.html#child_process_subprocess_stdio) as a starting point. – lependu Nov 19 '18 at 15:00
  • Ok. But how do I capture that input when prompted for? – Maarten Nov 19 '18 at 16:03

2 Answers2

7

Simply pipe all standard input from the parent process to the child and all output from the child to the parent.

The code below is a full wrapper around any shell command, with input/output/error redirection:

const { spawn } = require('child_process');
var child = spawn(command, args);

child.stdout.pipe(process.stdout);
child.stderr.pipe(process.stderr);
process.stdin.pipe(child.stdin);

child.on('exit', () => process.exit())

Note that if you pipe stdout you don't need handle the data event anymore.

mihai
  • 37,072
  • 9
  • 60
  • 86
  • That worked. I probably need to read-up some more about piping data in node. Any recommendations by any chance for good documentation on this subject? – Maarten Nov 26 '18 at 16:12
  • you should read about working with streams, that's the wider topic. The official node docs about [Stream](https://nodejs.org/api/stream.html) is a good starting point, but you can always google for more – mihai Nov 26 '18 at 16:18
  • Cool. Thanks mihai! – Maarten Nov 26 '18 at 16:24
  • Spawn has third argument - `options`. Pass `stdio` and then configure stdin, stdout, stderr pipes i.e. `spawn(command, args, { stdio: ["inherit", "inherit", "inherit"] })` More on stdio: https://nodejs.org/api/child_process.html#child_process_options_stdio – Lukas C Jun 15 '20 at 14:13
4
require( "child_process" ).spawnSync( "sh", [ "-c", "npm adduser" ], { stdio: "inherit", stdin: "inherit" } );

this will execute the command given as we normally do in terminal.

Deep patel
  • 71
  • 2