I created a program in C++ and created its executable File. My program reads from a huge chunk of files, and then I only need to perform computations on it. So in short I only want to run my executable file once and then just need to pass command line arguments to get the result.
const execFile = require('child_process').execFile;
const child = execFile('./a.out',[InArr], (error, stdout, stderr) => {
if (error) {
throw error;
}
console.log(stdout);
});
But the problem with the above line is, it will execute my code every single time, therefore I need to do all the extra work(reading files), again.
Is there some other way to do it more efficiently?
Related
I'm trying to mimic a terminal in node so I need to create a 'touch' function in node.js and I can't find anything that specifically uses touch. How can I set that up?
I've used a couple different things in the past but they keep getting kicked back because I'm not actually using 'fs.touch' or whatever it is.
this was my first attempt.
module.exports.touch = (filename, err) => {
if (err) {
throw err;
} else {
fs.openSync(filename, 'w');
`open filename`
}
};
this was my most recent attempt
module.exports.touch = (filename, callback) => {
open(filename, 'w', (err, fd) => {
err ? callback(err) : close(fd, callback);
});
};
The second one was essentially what they wanted because it did create a touch function but again they want me to actually use fs.touch but I cant find anything about it.
Make time either the current time or the time you want to be set:
fs.utimesSync(filename, time, time);
Just open the path file in write mode, and close it. You will have an empty file, equivalent at touch in command line
Example of codes that will execute command line using from Node.js. It will return full HTML of page.
const getPageHtmlResponse = (fullUrl) => {//fullUrl is come from input form in web page
return new Promise((resolve, reject) => {
try {
const exec = require('child_process').exec
exec("curl "+fullUrl, (err, stdout, stderr) => resolve(stdout))
} catch (error) {
resolve(false)
}
});
}
Is this code can be insecure? I mean the hackers can inject another command on it to manipulate the system or server?
If yes, there's good way to escape it or make it secure?
Don't use child_process.exec(). A clever crafted string from user input will launch arbitrary code from your program, which you do want to avoid.
Instead, use child_process.execFile() as follows:
const getPageHtmlResponse = (fullUrl) => {//fullUrl is come from input form in web page
return new Promise((resolve, reject) => {
try {
const execFile = require('child_process').execFile
execFile("/path/to/curl", fullUrl, (err, stdout, stderr) => resolve(stdout))
} catch (error) {
resolve(false)
}
});
}
execFile takes the pre-parsed list of commands and does not launch an intermediate shell, so there is less risk of launching a program through an untrusted URL.
See also
child_process.execFile
If the user writes a script and put it on http://blahblah.blah/b and instead of this URL it provides a tricky one: http://blahblah.blah/b | sh, now your code will create a process and execute curl http://blahblah.blah/b | sh. and the script could be anything.
one thing you should consider is that, to validate user input URL, check it to no contain extra commands, and be the only url.
I'm running Windows 10, and I have a program, let's call it program, that can be run from the command line. When run, it responds to commands the user enters. The user enters a command, presses the return key, and the program prints a response. I did not make this program and do not have the source, so I cannot modify it.
I want to run this program from within Node.js, and have my Node.js program act as the user, sending it commands and getting the responses. I spawn my program like this:
var spawn = require('child_process').spawn;
var child = spawn('program');
child.stdout.on('data', function(data) {
console.log(`stdout: ${data}`);
});
Then I attempt to send it a command, for example, help.
child.stdin.write("help\n");
And nothing happens. If I manually run the program, type help, and press the return key, I get output. I want Node.js to run the program, send it input, and receive the output exactly as a human user would. I assumed that stdin.write() would send the program a command as if the user typed it in the console. However, as the program does not respond, I assume this is not the case. How can I send the program input?
I've seen many similar questions, but unfortunately the solutions their authors report as "working" did not work for me.
Sending input data to child process in node.js
I've seen this question and answer and tried everything in it with no success. I've tried ending the command with \r\n instead of \n. I've also tried adding the line child.stdin.end() after writing. Neither of these worked.
How to pass STDIN to node.js child process
This person, in their self-answer, says that they got theirs to work almost exactly as I'm doing it, but mine does not work.
Nodejs Child Process: write to stdin from an already initialised process
This person, in their self-answer, says they got it to work by writing their input to a file and then piping that file to stdin. This sounds overly complicated to send a simple string.
This worked for me, when running from Win10 CMD or Git Bash:
console.log('Running child process...');
const spawn = require('child_process').spawn;
const child = spawn('node');
// Also worked, from Git Bash:
//const child = spawn('cat');
child.stdout.on('data', (data) => {
console.log(`stdout: "${data}"`);
});
child.stdin.write("console.log('Hello!');\n");
child.stdin.end(); // EOF
child.on('close', (code) => {
console.log(`Child process exited with code ${code}.`);
});
Result:
D:\Martin\dev\node>node test11.js
Running child process...
stdout: "Hello!
"
Child process exited with code 0.
I also tried running aws configure like this, first it didn't work because I sent only a single line. But when sending four lines for the expected four input values, it worked.
Maybe your program expects special properties for stdin, like being a real terminal, and therefore doesn't take your input?
Or did you forget to send the EOF using child.stdin.end();? (If you remove that call from my example, the child waits for input forever.)
Here is what worked for me. I have used child_process exec to create a child process. Inside this child process Promise, I am handling the i/o part of the cmd given as parameter. Its' not perfect, but its working.
Sample function call where you dont need any human input.
executeCLI("cat ~/index.html");
Sample function call where you interact with aws cli. Here
executeCLI("aws configure --profile dev")
Code for custom executeCLI function.
var { exec } = require('child_process');
async function executeCLI(cmd) {
console.log("About to execute this: ", cmd);
var child = exec(cmd);
return new Promise((resolve, reject) => {
child.stdout.on('data', (data) => {
console.log(`${data}`);
process.stdin.pipe(child.stdin);
});
child.on('close', function (err, data) {
if (err) {
console.log("Error executing cmd: ", err);
reject(err);
} else {
// console.log("data:", data)
resolve(data);
}
});
});
}
Extract the user input code from browser and save that code into a file on your system using fs module. Let that file be 'program.cpp' and save the user data input in a text file.
As we can compile our c++ code on our terminal using g++ similarly we will be using child_process to access our system terminal and run user's code.
execFile can be used for executing our program
var { execFile } = require('child_process');
execFile("g++", ['program.cpp'], (err, stdout, stderr) => {
if (err) {
console.log("compilation error: ",err);
} else{
execFile ('./a.out' ,['<', 'input.txt'], {shell: true}, (err, stdout, stderr) => {
console.log("output: ", stdout);
})
}
})
In this code we simply require the child_process and uses its execFile function.
First we compile the code present in program.cpp, which creates a default a.out as output file
Then we pass the a.out file with input that is present in input.txt
Hence you can view the generated output in your terminal and pass that back to the user.
for more details you can check: Child Processes
I am having a problem with async shell executes in node.js.
In my case, node.js is installed on a Linux operating system on a raspberry pi. I want to fill an array with values that are parsed from a shell script which is called on the pi. This works fine, however, the exec() function is called asynchronously.
I need the function to be absolute synchron to avoid messing up my whole system. Is there any way to achieve this? Currently I am trying a lib called .exe, but the code still seems to behave asynchron.
Here's my code:
function execute(cmd, cb)
{
child = exec(cmd, function(error, stdout, stderr)
{
cb(stdout, stderr);
});
}
function chooseGroup()
{
var groups = [];
execute("bash /home/pi/scripts/group_show.sh", function(stdout, stderr)
{
groups_str = stdout;
groups = groups_str.split("\n");
});
return groups;
}
//Test
console.log(chooseGroup());
If what you're using is child_process.exec, it is asynchronous already.
Your chooseGroup() function will not work properly because it is asynchronous. The groups variable will always be empty.
Your chooseGroup() function can work if you change it like this:
function chooseGroup() {
execute("bash /home/pi/scripts/group_show.sh", function(stdout, stderr) {
var groups = stdout.split("\n");
// put the code here that uses groups
console.log(groups);
});
}
// you cannot use groups here because the result is obtained asynchronously
// and thus is not yet available here.
If, for some reason, you're looking for a synchronous version of .exec(), there is child_process.execSync() though it is rarely recommended in server-based code because it is blocking and thus blocks execution of other things in node.js while it is running.
I have a program which reads a large file from a stream and writes it to a file.
Here's reading the file from stream
var stream = new Stream.PassThrough();
Request(options, function (error, res, body) {
if (error) {
Logger.error('ProxyManager', 'getStream', error);
return callback(error);
}
}).pipe(stream); // first pipe call
Here's writing the file
var outputFile = fs.createWriteStream(filePath);
stream.pipe(outputFile); // second pipe call
My problem is the process takes a lot of memory when transferring a large file which seems like pipe is keeping the whole file in the memory in the first pipe or the second call. Can anyone help with this?