extra-child-process
Version:
Useful additions to inbuilt child_process module.
166 lines (139 loc) ⢠7.87 kB
Markdown
Useful additions to inbuilt [child_process] module.<br>
š¦ [Node.js](https://www.npmjs.com/package/extra-child-process),
š [Files](https://unpkg.com/extra-child-process/),
š° [Docs](https://nodef.github.io/extra-child-process/).
Have you heard of [bash] or [command prompt]? These programs are called **shells**.
They **watch what you type**, and treat it as requests to **run particular programs**.
Programs themselves are just names on the *file system*, and the shell **searches**
**them in a particular manner** (controlled with *environment variables* such as [PATH]).
Our programs as based on [UNIX principles], where each program can accept an
**initial input** through **arguments**, **runtime input** through `stdin` *input stream*
`
with `stderr` *output stream* `
into another program through **piping** `|`, allowing us to **set up a pipline** of
programs to achieve a **complex operation** (without having to write a new program).
[] is an **inbuilt Node.js module** that enables us to *execute specific*
*programs directly* ([execFile]), *or through the shell* ([exec]). **Executing**
**programs through the shell** is hyper convenient as we are allowed to *use its*
*inbuilt commands and features* such as *piping of streams*, but is does come with a
**security risk** (such as [command injection]) **when using unsanitized user input** to
generate the sequence of instructions to be executed on the shell. When possible,
**execting specific programs directly** using [execFile] would be a suitable approach.
[] can be used when we want to start a new process and **control** its *input* and
*output streams*. [exec] and [execFile] are implemented on top of [spawn]. [fork] is a
special case of [spawn], used specifically to launch *new Node.js* processes.
This package provides **async versions of functions** (in additon to the
existing *sync* and *callback*-based functions), which are not included with the
inbuilt `child_process` module. They are named as `*Async` can be used with
`Promise`-based asynchronous programming using the `await` keyword. [spawnAsync]
is a special case here, which returns a `PromiseWithChild` which is essentially
a `Promise` with a `.child` property to allow `ChildProcess` to be directly
accessed similar to [spawn]. In addition, **callback-based functions**, such as
[], also **behave as async functions** when a *callback* is **not provided**.
Functions for **locating path of executable(s)** such as [which] and [whichAll]
are also included. Design was based on local ideas and [literature survey].
> Stability: [Experimental](https://www.youtube.com/watch?v=L1j93RnIxEo).
[child_process]: https://nodejs.org/api/child_process.html
[bash]: https://en.wikipedia.org/wiki/Bash_(Unix_shell)
[command prompt]: https://en.wikipedia.org/wiki/Cmd.exe
[PATH]: https://superuser.com/q/284342/305990
[UNIX principles]: https://www.youtube.com/watch?v=tc4ROCJYbm0
[command injection]: https://www.stackhawk.com/blog/nodejs-command-injection-examples-and-prevention/
[literature survey]: https://gist.github.com/wolfram77/d936da570d7bf73f95d1513d4368573e
<br>
```javascript
const xcp = require('extra-child-process');
// 1. List files in current directory.
async function example1() {
var {stdout, stderr} = await xcp.exec('ls -a');
var {stdout, stderr} = await xcp.execFile('ls', ['-a']);
xcp.exec('ls -a', (err, stdout, stderr) => 0);
xcp.execFile('ls', ['-a'], (err, stdout, stderr) => 0);
// ā .
// ā ..
// ā .build
// ā .git
// ā .github
// ā ...
}
example1();
// 2. List files in 'src' directory.
async function example2() {
var {stdout, stderr} = await xcp.exec('ls -a', {cwd: 'src'});
var {stdout, stderr} = await xcp.execFile('ls', ['-a'], {cwd: 'src'});
xcp.exec('ls -a', {cwd: 'src'}, (err, stdout, stderr) => 0);
xcp.execFile('ls', ['-a'], {cwd: 'src'}, (err, stdout, stderr) => 0);
// ā .
// ā ..
// ā index.ts
}
example2();
// 3. Locate path of node executable.
async function example3() {
var paths = process.env.PATH.split(';');
var exec = await xcp.which('node');
var exec = await xcp.which('node', {paths});
// ā 'D:\\Program Files\\nodejs\\node.exe'
}
example3();
// 4. Locate path of n*e executables.
async function example4() {
var paths = process.env.PATH.split(';');
var execs = await xcp.whichAll(/^n.*?e$/);
var execs = await xcp.whichAll(/^n.*?e$/, {paths});
// ā [
// ā 'D:\\Program Files\\Git\\usr\\bin\\nice.exe',
// ā 'C:\\Program Files\\NVIDIA GPU Computing Toolkit\\CUDA\\v11.2\\bin\\nvprune.exe',
// ā 'D:\\Program Files\\nodejs\\node.exe'
// ā ]
}
example4();
```
<br>
<br>
| Property | Description |
| ---- | ---- |
| [exec] | Execute a command within a shell, buffering any output. |
| [execFile] | Execute an executable without a shell by default, buffering any output. |
| [fork] | This method is a special case of spawn used specifically to spawn new Node.js processes. |
| [spawn] | This method spawns a new process using the given `command` and `args`. |
| [spawnAsync] | Spawn new process using given command and arguments. |
| [which] | Locate path of executable for given command. |
| [whichAll] | Locate paths of all matching executables for given command. |
<br>
<br>
- [Node.js Child process API](https://nodejs.org/api/child_process.html#child_processexeccommand-options-callback)
- [spawncommand package](https://www.npmjs.com/package/spawncommand)
- [async-execute package](https://www.npmjs.com/package/async-execute)
- [spawndamnit package](https://www.npmjs.com/package/spawndamnit)
- [async-child-process package](https://www.npmjs.com/package/async-child-process)
- [child-command package](https://www.npmjs.com/package/child-command)
- [exec-then package](https://www.npmjs.com/package/exec-then)
- [child-process-async package](https://www.npmjs.com/package/child-process-async)
- [faithful-exec package](https://www.npmjs.com/package/faithful-exec)
- [child-process-promise package](https://www.npmjs.com/package/child-process-promise)
- [superspawn package](https://www.npmjs.com/package/superspawn)
- [await-exec package](https://www.npmjs.com/package/await-exec)
- [command package](https://www.npmjs.com/package/command)
- [spawn-please package](https://www.npmjs.com/package/spawn-please)
- [process-promises package](https://www.npmjs.com/package/process-promises)
- [ts-process-promises package](https://www.npmjs.com/package/ts-process-promises)
- [child-process-es6-promise package](https://www.npmjs.com/package/child-process-es6-promise)
- [promise-exec package](https://www.npmjs.com/package/promise-exec)
- [promisify-child-process package](https://www.npmjs.com/package/promisify-child-process)
- [which package](https://www.npmjs.com/package/which)
<br>
<br>
[](https://www.youtube.com/watch?v=GW2g-5WALrc&list=PLEaaT3oTjHIdDH5DSL-hAOEhe8KGCt93J)
[](https://nodef.github.io)
[](https://zenodo.org/badge/latestdoi/483206539)

[]: https://github.com/nodef/extra-child-process/wiki/exec
[]: https://github.com/nodef/extra-child-process/wiki/execFile
[]: https://github.com/nodef/extra-child-process/wiki/fork
[]: https://github.com/nodef/extra-child-process/wiki/spawn
[]: https://github.com/nodef/extra-child-process/wiki/spawnAsync
[]: https://github.com/nodef/extra-child-process/wiki/which
[]: https://github.com/nodef/extra-child-process/wiki/whichAll