Node/Electron exec Rscript misses library paths - javascript

The basic setup of the project I'm working on (Windows) is an Electron app which communicates with R via R serve. Now everything is working fine except one thing thats been driving me crazy lately.
The problem is that when I use node from cmd (etc. node startR.js) and execute an R script with a command like this:
var exec = require('child_process').exec;
var executableR = exec('Rscript startR.R', function(error, stdout, stderr) {
console.log(stdout);
});
and R code like:
library('Rserve')
Rserve()
everything goes fine. But, when I try to execute the very same line in the main.js (entrypoint) file for my Electron app, I get the error that the R libraries (i.e. Rserve) can't be found from within R.
I have checked for possible causes for this and I have found out that R library paths differ (.libPaths()) when R is called from cmd node and from electron. Namely, R libs are installed in MyDocuments folder, and R called from cmd node seems to see them properly. On the other hand, the same exec from electron makes R see only the default library path (in program files where R is installed), so it fails to find libraries.
I know that this must be environment issue (like its run from an environment different from the current user), but I'm pretty uncertain what to try. I thought that passing process.env to {env: } options for child_process.exec but to no avail.

Related

How to run child_process.exec correctly on an ajax request?

There is a server, that I have an access to, but do not have ownership on. It serves a node js / express application on a default port 3000. There are several scripts, that are usually run either manually from the terminal or by cron job. What I want to do is to have a button on the client-side and make an ajax request to a certain route and execute a node js command with inline arguments. For example:
node script.js 123
All routes are set and working. I have a CliController file that handles requests and has to run the command above. Currently I am using the following code:
cp.exec(`node script.js ${ip}`, function (err, stdout, stderr) {
if (err) {
console.log(err);
}
console.log(stdout);
console.log(stderr);
});
The script.js file is in root folder of the project, but the project itself was built by using express-generator and is being served using node bin/www command. There is a service/process on the server that runs nodemon to restart this project if it fails as well. Therefore I do not have access to output of that particular process.
If I run the command above in the terminal (from the root folder of the project, to be precise), it works fine and I see the output of the script. But if I press the button on the webpage to make a request, I am pretty sure that the script does not execute, because it has to make an update to database and I do not see any changes. I also tried to use child_process.spawn and child_process.fork and failed to get it working.
I also tried to kill nodemon and quickly start the project again to the see console output. If I do this, everything works.
What am I doing wrong ?
The process invoked may be in a blocking state, hence the parent script is simply waiting for the children process to terminate, or return something.
We can avoid this behaviour right into the shell command, by adding & (ampersand control operator) at the end.
This makes a command running in the background. (Notice, you can still control the children(s) process using the PID's and POSIX signals, this is another subject, but very related and you might find it very handy pretty soon).
Also notice that killing/stopping the parent script will also kill the children(s). This can be avoided using nohup.
This is not linked to JavaScript or node.js, but to bash, and can be used with anything in the shell.
cp.exec(`node script.js ${ip} &`, function (err, stdout, stderr) {
if (err) {
console.log(err);
}
console.log(stdout);
console.log(stderr);
});
Bash reference manual

nodejs print file with child-process

I'm learning nodejs and I want to send some file to the printing queue.
I tried elctron-printer and node-printer modules but actually they do not work proprly (can't detect printer with printer.list command for example). Now I'm trying to make it with child_process module and I want to know is there any posibility to start file with its associated application with "print" argument like a python can do it?
For example, this is a code sample of file execution with nodejs:
var childProcess = require('child_process');
childProcess.exec('start printme.txt', function (err, stdout, stderr) {
if (err) {
console.error(err);
return;
}
console.log(stdout);
process.exit(0);// exit process once it is opened
})
Unfortunately it seems that "print" argument is invalid for this code.
And this is a code sample for python and it works fine on windows:
import os
os.startfile('printme.txt', 'print')
All in all I hope that there is possibility to emulate system commands with nodejs.
Otherwise I will have to execute python script via nodejs just for file printing, something like this:
let python = spawn('python', [path.join(app.getAppPath(), '..', 'python_scripts/print_file.py'])
But it is terrible way to do it.

NodeJS: Run dot slash command line Windows

I'm trying to get the following code which should execute shell command to wor in OSX and Windows.
const exec = require("child_process").exec;
const runCommand = (cmd) => exec(cmd,
function (error, stdout, stderr) {
if (stdout.length > 0) {
console.log(stdout);
}
});
For the following runCommand("./node_modules/.bin/someBinary") it does not work in Windows. But it works fine in OSX. So I wonder what modifications do I need for it to run in Windows as well?
Have you considered giving a try at npm-exec ?
Loads the same environment that would be present for npm run-script , but executes arbitrary bash command lines. (even on windows! Thanks to bashful). This includes modifying $PATH so scripts in node_modules/.bin will be used before global modules.
So you could npm-exec someBinary instead of using a relative path breaking Windows / OSX compatibility
If this module does not suit you, you can also give a try at npm bin as explained in this answer.
Okay, so in the end I solved it with checking which platform I'm in and in turn I just wrote the same command with OS specific so it would run.
In short I used process.platform to find out which OS it is. Not the most elegant. But at least it solved my problem.

Can programs be written with JavaScript that run Windows 8 terminal commands when a gui button is clicked?

I know Windows 8 'apps' can be developed using web technologies but I haven't been able to find out if terminal commands can be run in the background using web technologies as an interface. I basically have mongoDB on my computer and it takes two terminal windows open to run it. I thought it might be a neat project to see if I could write a little app that is nothing more than a button that launches both commands behind the scenes saving me the hassle of going to the directories and running the commands manually for both terminal windows.
If you plan to launch apps via server-side JavaScript (e.g. node.js), use the child_process module..
The workflow would be that in the windows 8 gui side, it will just issue a request to your own local server in node.js, then it would execute those commands.
Example:
var exec = require('child_process').exec;
var child = exec("insert command here", function(err, stdout, stderr) { });
See examples exec and spawn for more examples.
======
Another thing you can do is create a batch (.bat) file that contains those two commands needed for your mongodb instance and put that as a shortcut in the Windows 8 Start Screen.
It depends on what kinds of commands you need to execute, and when and where. If you plan to execute commands remotely, I'd assume server-side JS would be appropriate, but if you plan to execute commands locally, I think all you need is just batch scripting.

How do you get webdriverjs working?

Anyone here have experience using Selenium and webdriverjs? I'm coming from a non-Java background with a good deal of experience with Node.js and JavaScript in general. According to the Selenium docs, you have to set-up a stand-alone Selenium server to use the node web driver. Fortunately, they seem to be bundled together.
npm install webdriverjs
gets you the JAR file for the standalone selenium server inside the node_modules/webdriverjs/bin directory. Example tests are inside the node node_modules/webdriverjs/examples directory but the tests in them fail when I run them from either the webdriverjs or examples directories.
What's the missing piece here? What's the quickest way to get up and running?
I have read the docs.
Note: Stack overflow wouldn't let me use the tag webdriverjs, but this is specifically about webdriverjs, not using selenium with Java or other languages.
Update: The only problem was that the built-in example tests are broken!
Here's what I did to get webdriverjs working:
Step 1: start selenium standalone in my laptop by running command java -jar selenium-server-standalone-2.33.0.jar. then it will listen to http://localhost:4444/ and you can access it via http://localhost:4444/wd/hub/. You also need to make sure Firefox browser is installed on your laptop.
Step 2: create a new directory and run command npm install webdriverjs.
Step 3: create a new file named test_webdriverjs.js in the new directory you created, and it looks like this:
var webdriverjs = require('webdriverjs');
var client = webdriverjs.remote({
host: 'localhost',
port: 4444
});
client.init();
client.url('https://github.com/')
.getTitle(function(err, title) { console.log (title)}).call(function () {});
client.end();
Then run command node test_webdriverjs.js under the same directory and you will find it works. If it doesn't work, paste out the console output.

Categories