I'm looking for a way to print in a webpage the status of the execution of a shell command.
Using NodeJS and a module called sudo-js I execute a command that in shell prints the status of the execution, the problem is that I just print all the progress at the end of the execution in the website, but I would like to print that in real time as in shell terminal into the webpage.
Here is my code
if (err) {
console.log(err.stack);
} else {
var command = ['ansible-playbook', '-i', 'hosts.txt', 'sample.yaml'];
sudo.exec(command, function(err, pid, result) {
console.log(result);
res.render('mensajeScriptEjecutadoConResultado', {Resultado: result});
});
}
})
I know that console.log() doesn't work in showing data by buffer or in real time, and sudo.exe() may not work like this too, so how to do that?.
Thank you!.
Take a look at Child Process module, which includes some helpful examples. Your node program can react to standard output, error and process completion.
I use this to report the current status of a child process to web clients... but I didn't make it continuous like #Barmar mentions; my client has to refresh to get the status.
Related
I have a nodejs function which calls a ShellScript xyz.sh. This shell script executes a jar file abc.jar and prints some output in the console. I am able to see some output lines from jar file execution in the console. But I am not able to capture them lets say to a variable. My requirement is to capture the error while executing logic present in jar file. Try catch is not helping here. Also, I cannot edit the java code and rebuild the jar file. But I would need to capture the output of jar file execution somehow in Nodejs and in case of errors while executing logic inside jar file, I need to take certain actions based on the error. So, can someone help me on how to capture the output of jar file in nodejs.
private async function_exec(abc: string) {
log.info('inside func_exec')
let result;
try
{
result = await asyncExec(
call xyz.sh; --> shell script gets called here
)
}
catch(error)
{
log.info('error is '+error);
}
log.info('result is '+result);
}
Output looks like below. I need to somehow capture messages like "Processing..",'Failed to Execute","Invalid system ID"
output:
runn_1 inside func_exec
runn_1 Processing..
runn_1 Failed to Execute
runn_1 Invalid system ID
runn_1 error is 1
runn_1 result is undefined
I am currently working on the back end of an application, using NodeJS. As part of my code, I read the first line of a file and send that to a client using res.json. My code looks like this
var hr = 'head -n 1 ../' + req.file.path + '_hr.txt';
exec(hr, function (error, stdout, stderr) {
console.log(hr);
console.log(stdout);
console.log(stderr);
res.json({
"heartrate": stdout
});
})
When I execute this however, I get
{"heartrate" : ""}
even though on the console of the back end I see a value for stdout.
I have looked at other related questions but the information I've got has been in bits and pieces. I realise the object produced by stdout is not a string. I tried the toString() method on it but that didn't work.
I also put an if(stdout) around the res.json since exec is ansynchronous and may stdout may not have been written to at the point when I call console.log(stdout), but that also did not work.
I also tried using spawn instead of exec to no avail, although I may have used it wrongly. I'm sure the solution to my problem is very simple, but I have not been able to find it. Any help will be appreciated!
So it turns out I was logging the wrong stdout, logged the right one and got the answer I wanted
I am new to express and am trying to wrap my head around callbacks in RESTful actions. In my PUT request below, I'm confused about the following line that I have bolded below. Why is response.pageInfo.book being set to the second parameter in the anonymous function (result)? that seems kind of arbitrary.
Also, what is the best way to inspect some of these parameters (req, res, result, etc)? When I console.log it, doesn't show up in my terminal or in my browser console.
exports.BookEdit = function(request, response) {
var id = request.params.id;
Model.BookModel.findOne({
_id: id
}, function(error, result) {
if (error) {
console.log("error");
response.redirect('/books?error=true&message=There was an error finding a book with this id');
} else {
response.pageInfo.title = "Edit Book";
**response.pageInfo.book = result;**
response.render('books/BookEdit', response.pageInfo)
}
})
}
The findOne function takes a query ({_id : id}) and a callback as arguments. The callback gets called after findOne has finished querying the database. This callback pattern is very common in nodejs. Typically the callback will have 2 arguments
the first one error is only set if there was an error.
the second one usually contains the value being returned. In this case you are finding one book in the database.
The line you have bolded is where the book object is assigned to a variable which will be sent back to be rendered in the browser. It is basically some javascript object.
Your second request, to debug this stuff, here is what you can do:
In you code type the word debugger;
e.g.
var id = request.params.id;
debugger;
Next, instead of running your program like this:
node myprogram.js
... run with debug flag, i.e.
node debug myprogram.js
It will pause at the beginning and you can continue by pressing c then Enter
Next it will stop at that debugger line above. Type repl and then Enter and you'll be able to inspect objects and variables by typing their names.
This works very well and requires no installation. However, you can also take a more visual approach and install a debugger such as node-inspector which does the same thing but in a web browser. If you use a good IDE (e.g. webstorm) you can also debug node.js pretty easily.
In the above, the document that is the result of the findOne() query is being added to the pageInfo key of the response and is then being rendered in a template. The first parameter is a potential error that must be checked and the remainder contain data. It's the standard node idiom that an asynchronous call returns to a callback where you do your work.
The writer of the code has also decided to decorate the response object with an extra attribute. This is often done when a request passes through a number of middleware functions and you might want to build up the response incrementally (for example having a middleware function that adds information about the current user to the pageInfo key).
Look and see what else is on response.pageInfo. Information was probably put there by previous middleware (especially since the function above expects the pageInfo key to exist). Just do a console.log(response.pageInfo) and look on your server log or standard out.
This GitHub issue documents that the console doesn't output anything to the meteor shell. Are there any workarounds? By default all console.log() statements will be output in the app's STDOUT (not in the shell).
Let's say we want to print certain items from a collection:
Meteor.users.find().forEach(function (user) {
if (...) console.log(user.emails[0].address;
});
That won't print anything. Here's what I've tried:
process.stdout.write() - doesn't print anything
Create a string buffer, append what we want to log to it, and evaluate it.
var output = '';
Meteor.users.find().forEach(function (user) {
if (...)
output += user.emails[0].address + "\n"
});
output;
This works but the \n is echoed literally, not as a line feed.
Evaluate the expression in the function. Predictably, this doesn't print anything.
One workaround I've used is to run the app in the background, then run the shell in the same window. i.e.
meteor run &
meteor shell
That way, everything that gets output in the app's console gets printed to your window. Admittedly, this won't help if you want to log only specific messages to your shell, but it helps if all you want is to avoid switching back and forth between multiple windows all the time.
I'm getting the "Error: Trying to open unclosed connection," but I don't believe it's due to a db issue... and that's why I'm stumped. Most solutions to this error, reference db connection issues.
My goal here is execute an external process. If the process closes with anything other than exit code 0, I want to email an alert for example.
I was using the child.on('close', function(code).... to get the exit value from the external process (coming back as "code") So if code !=0 I want to do something... maybe rerun the test... maybe call a different method that sends an email, etc.
Each time I attempt to call a method, from within child.on('close'), I get the error "Trying to open unclosed connection." Which is why I'm also handling the save action in the same block.
Code Sample:
var spawn = require('child_process').spawn,
child = spawn('sipp', ['-s', dnis,server, '-sn', scenario, '-m', '1','-i','127.0.0.1','-recv_timeout','1000']);
}
child.on('close',function(code){
if(code != 0){
Call().emailAlert(dnis, server, scenario, type, carrier);
}
var TestResults = mongoose.model('test_results', TestResultsSchema);
// Saving results to MongoDB
var result = new TestResults({
testType: type,
dnis: dnis,
server: server,
result: code,
carrier: carrier,
date: Date.now()
});
result.save(function (err) {if (!err) {console.log ('Successful Save!')}
else{console.log(err)}});
});
};
If I remove:
if(code != 0){
Call().emailAlert(dnis, server, scenario, type, carrier);
}
The error goes away. What's the best way for me to capture the exit code of the process, and based on it, make a call to a different method (i.e. to email an alert) in Node.js?
I guess I was wrong. I changed the mongoose.connect to mongoose.createConnection and this specific error went away... but unfortunately I'm left with more errors. I'll open up the main question in a different topic.