0

I want to spawn a child process, and then at a later time send an argument to it that will then execute. How can I do that? (NodeJS, on Mac)

For example, I have a command to execute a script file:

osascript script-test.scpt

This command works in the terminal, and it also works using exec, like so:

const { exec } = require('child_process')
var script = 'osascript script-test.scpt'
exec(script)

But how do I get it to work in an already running child process?

I've tried the following, but nothing happens (no errors, and no activity):

const { spawn } = require('child_process')
var process = spawn('osascript')
...
[at some later point (after spawned process has been created)]

process.stdin.write('script-test.scpt')
SeanRtS
  • 1,005
  • 1
  • 13
  • 31

1 Answers1

1

In all current operating systems, a process is spawned with a given set of arguments (also called argv, argument values) and preserves this set until execution ends. This means that you cannot change arguments on the fly.

For a program to support multiple job submissions after spawning, it needs to implement this explicitly using some form of communication - this is known as IPC, or Inter-Process Communication. A program that supports IPC will usually allow another program to control its behavior to some extent - for example, submit jobs for processing and report back on their completion.

Popular methods of implementing IPC include:

  • Network communication
  • Local calls via a "message bus" such as D-Bus
  • Pipes (direct communication over stdin/stdout)

Inspect the documentation for program that you're trying to call and find out if it supports any form of control, out of the ones listed above. If yes, you may be able to integrate (in a program-specific way) with it. If not, then you will need to spawn a new instance every time you need to process a new job.

Robert Kawecki
  • 2,218
  • 1
  • 9
  • 17
  • Thanks for your reply. In the example I noted, I'd be running the equivalent of a shell command to process osascript. Do you have code (pseudo-code is fine) in mind for how pipes would work in that case? – SeanRtS Nov 11 '21 at 12:16
  • For pipes to work and control osascript, the osascript program must support it - you must be able to write lines to it, and it should respond with results for each line that you gave it. Does it work that way? If not, then there is no programmatic way to make it interactive and you'll just have to spawn 1 instance per job. – Robert Kawecki Nov 11 '21 at 14:27
  • That's helpful. osascript--as I use it--activates scripting on mac, and is a command you can use in bash/the shell, like "$ osascript [scripting command]". What do you mean by write lines to it? (I'm not sure what that would look like) – SeanRtS Nov 11 '21 at 14:33
  • Take `python`, for example. You can run just `python`, write "2+2", press [Enter] - you get "4" back. Write another line to evaluate - you get another result. If osascript does not work this way, but instead expects a whole program before processing it in its entirety - then you won't be able to use this method, and will have to spawn() each time. – Robert Kawecki Nov 11 '21 at 14:49
  • Thanks--I'll have to test it out. Assuming it works, is piping normally a line like: process.stdin.pipe(myREPL.stdin, { end: false }); (described here:https://nodejs.org/en/knowledge/advanced/streams/how-to-use-stream-pipe/) – SeanRtS Nov 11 '21 at 14:56
  • 1
    Here's a question where the OP is already successfully piping data to/from another process, interactively: https://stackoverflow.com/questions/31615069/childprocess-stdin-not-getting-read-by-python-readline - note the answer is wrong, as the missing part was a newline, not .end()! – Robert Kawecki Nov 11 '21 at 15:17