This question already has answers here:
What's the meaning of "=>" (an arrow formed from equals & greater than) in JavaScript?
(14 answers)
Closed 6 years ago.
I read nodejs 5.4 docs, where I found a => symbol in an example and a new way to define callback function. I don't know why => is used ? is it really a new way to define callbacks ? This is the example from node 5.4 docs.
const spawn = require('child_process').spawn;
const ls = spawn('ls', ['-lh', '/usr']);
ls.stdout.on('data', (data) => {
console.log(`stdout: ${data}`);
});
ls.stderr.on('data',(data) => {
console.log(`stdout: ${data}`);
});
ls.on('close',(code) => {
console.log(`child process exited with code ${code}`);
});
It is an EcmaScript 6 arrow function.
It isn't just node.js specific. It works in modern web browsers too.
Related
I wrote java program that takes one argument and writes it.
Also, it reads lines and writes them.
Then, I compiled it and ran from Typescript (vscode extension).
const { spawn } = require('node:child_process');
const runJava = spawn('java', ['-cp', 'extension1/src', 'package.Main', 'aaa']);
runJava.stdout.on('data', (data: String) => {
console.log(`stdout: ${data}`);
});
runJava.stderr.on('data', (data: String) => {
console.error(`stderr: ${data}`);
});
runJava.on('close', (code: Number) => {
console.log(`child process exited with code ${code}`);
});
It writes 'aaa' to stdout successfully.
What do I need to do next to send some text to it?
I tried to write with echo, but that didn't work.
I encountered a weird issue with setTimeout inside a promise in a child process.
These are my files:
index.js:
const {spawnSync} = require('child_process');
const {resolve} = require('path');
const timeoutPromiseModule = resolve(__dirname, '.', 'timeout-promise');
const {stdout} = spawnSync('node', [timeoutPromiseModule]);
console.log(stdout.toString());
timeout-promise.js:
Promise.race([
Promise.resolve(),
new Promise((resolve, reject) => {
setTimeout(() => {reject('too long')}, 10000);
})
])
.then(x=> console.log('resolved'))
.catch(e => console.log('rejected'));
When I run node index.js I expected the output to be print immediatly but what actually happens is that the output hangs until setTimeout's callback is called by the child process.
What's causing this and how can this be resolved?
I'm guessing it's something to do with the child process's event loop that prevents the child process from closing until the messages empty?
I uploaded the code to GitHub for your convenience:
https://github.com/alexkubica/promise-race-settimeout-blocking-inside-child-process
The reason for this is that spawnSync will not return until the child process has fully closed as stated in the documentation:
The child_process.spawnSync() method is generally identical to
child_process.spawn() with the exception that the function will not
return until the child process has fully closed. [...]
Note that a node script will only exit when there are no more pending tasks in the eventloop's queue, which in this case happens after the timeout has resolved.
You can switch to spawn to see the immediatley resolved promise output:
const res = spawn('node', [timeoutPromiseModule]);
res.stdout.on('data', (data) => {
console.log(`stdout: ${data}`);
});
res.on('close', (code) => {
console.log(`child process exited with code ${code}`);
});
Consider a simple example below where I'm printing the response from a long-running command as it sends.
const { spawn } = require('child_process');
const ping = spawn('ping', ['www.google.com']);
ping.stdout.on('data', (data) => {
console.log(`stdout: ${data}`);
});
ping.stderr.on('data', (data) => {
console.error(`stderr: ${data}`);
});
ping.on('close', (code) => {
if (code !== 0) {
console.log(`ping process exited with code ${code}`);
}
});
This works ok. But when I try to pipe this result to grep, it stops working.
See sample below
const { spawn } = require('child_process');
const ping = spawn('ping', ['www.google.com']);
const grep = spawn('grep', ['bytes'])
ping.stdout.on('data', (data) => {
grep.stdin.write(data)
});
ping.stderr.on('data', (data) => {
console.error(`stderr: ${data}`);
});
ping.on('close', (code) => {
if (code !== 0) {
console.log(`ping process exited with code ${code}`);
}
grep.stdin.end();
});
grep.stdout.on('data', (data) => {
console.log(`stdout: ${data}`);
});
grep.stderr.on('data', (data) => {
console.error(`stderr: ${data}`);
});
grep.on('close', (code) => {
console.log(`grep process exited with code ${code}`);
});
The above code does not give me any results.
It looks like it is waiting for the first command to end before it pipes the result to the next.
I observed this by experimenting with the ls command.
Isn't the whole point of piping not to wait? Or am I missing something here?
Some variations I tried to no success:
ping.stdout.pipe(grep.stdin); instead of grep.stdin.write(data), although I don't believe there is much difference between the two.
const ping = spawn('sh', ['-c', 'ping www.google.com | grep bytes']); I have tried this with non-long-running commands and it works ok including the pipe and everything.
The problem is that grep block-buffers its output by default, so until several kilobytes of output are available, it won't send anything back to node. Note that if you waited long enough with your program as-is, you'd eventually see dozens of lines all suddenly returned at once. The --line-buffered option changes this, so do spawn('grep', ['--line-buffered', 'bytes']) instead of spawn('grep', ['bytes']).
I know there have been variations on this question, but none seem to cover this particular problem.
I am spawning a child process and attempting to send the output to the browser. The issue is the ansi coloring is not making it to the output.
I've imported ansi-to-html to render the ansi output if I receive it, but my spawned child is not preserving the output.
const process = spawn(
'bash',
[
'-ic',
'<command I am running>'
],
);
process.stdout.on('data', (data) => {
console.log(`stdout: ${data}`);
self.terminalOutput += convert.toHtml(`${data}`);
});
process.stderr.on('data', (data) => {
console.log(`stderr: ${data}`);
self.terminalOutput += convert.toHtml(`${data}`);
});
process.on('close', (code) => {
console.log(`child process exited with code ${code}`);
self.terminalOutput += convert.toHtml(`child process exited with code ${code}`)
});
So it looks like I found an answer here. `${data}` was implicitly converting the the data returned from the spawned process (I believe by doing type conversion implicitly calling toString() but I could be wrong here).
So to correctly pass the data to ansi-to-html, you must just pass it directly
process.stdout.on('data', (data) => {
self.terminalOutput += convert.toHtml(data);
});
process.stderr.on('data', (data) => {
self.terminalOutput += convert.toHtml(data);
});
For me setting the environment variable FORCE_COLOR=1 results in the data including ansi format string.
I am wondering what the correct way is to add "execArgs" to a Node process -
we have:
const cp = require('child_process');
const n = cp.spawn('node', ['some-file.js'], {});
but what if I want to add an execArg like so:
const n = cp.spawn('node --harmony', ['some-file.js'], {});
I don't think that is the right way to do it, and the docs don't seem to demonstrate this?
Is this the correct way?
const n = cp.spawn('node', ['--harmony','some-file.js'], {});
According to the docs for child_process.spawn() it clearly states that args is an array of string arguments that is passed in as the second argument.
The child_process.spawn() method spawns a new process using the given command, with command line arguments in args. If omitted, args defaults to an empty array.
A third argument may be used to specify additional options, with these defaults:
{ cwd: undefined, env: process.env }
Example of running ls -lh /usr, capturing stdout, stderr, and the exit code:
const spawn = require('child_process').spawn;
const ls = spawn('ls', ['-lh', '/usr']);
ls.stdout.on('data', (data) => {
console.log(`stdout: ${data}`);
});
ls.stderr.on('data', (data) => {
console.log(`stderr: ${data}`);
});
ls.on('close', (code) => {
console.log(`child process exited with code ${code}`);
});
Based on the above pulled from the child_process docs, the below would be correct.
const n = cp.spawn('node', ['--harmony','some-file.js']);