automatically input to terminal, from nodeJS? - node.js

This may sound rather crazy,
but I cannot find a solution to automate taking screenshots on a cordova application.
I know I can take and save a screenshot of the emulator using
adb shell /system/bin/screencap -p /sdcard/screenshot.png
adb pull /sdcard/screenshot.png screenshot.png
in the terminal, my crazy question is.
Can I trigger these commands from a nodeJS automation script? or is this too far fetched and a terrible idea?

Simplest way to execute terminal commands from node.js would be to use child_process.exec
const exec = require('child_process').exec;
exec('adb shell /system/bin/screencap -p /sdcard/screenshot.png', (error, stdout, stderr) => {
if (error) {
console.error(`exec error: ${error}`);
return;
}
console.log(`stdout: ${stdout}`);
console.log(`stderr: ${stderr}`);
});
The built-in child_process module in node.js provides many functions such child_process.spawn, child_process.exec, child_process.execFile which can be used to execute terminal commands or other script files (.sh, .bat).

Related

Run ffmpeg from its parent directory in node js application in its own directory

I have a node js application which needs to access ffmpeg. My approach to this has been to use {exec} from the child_processes module built into Node. The problem is that {exec} always starts the cmd line from the current directory and I can't figure out how to point the directory context to where ffmpeg.exe is located so that I can access the program. Is my approach flawed? How can I access a seperate CLI application from Node?
This code returns "'ffmpeg' is not recognized as an internal or external command" because I'm obviously in Node's execution context which is not where ffmpeg is located.
I also do not want to store the node application in the directory of ffmpeg.exe because that's just lazy and impractical.
exec(`ffmpeg -i ${filepathToMedia} --vf fps=1 ${outputdirectory}/out%d.png`, (error, stdout, stderr) => {
if (error) {
console.log(`error: ${error.message}`);
return;
}
if (stderr) {
console.log(`stderr: ${stderr}`);
return;
}
if(stdout) {
console.log(`success: ${stdout}`)
} });
You could do one of two things here:
Use the absolute path to the ffmpeg executable so instead of just exec('ffmpeg ...') you'd do something likeexec('C:\Users\user\ffmpeg_dir\ffmpeg ...') This isn't very clean and will probably break if someone else tries to use your code.
Add your ffmpeg directory to your system's PATH environment variable. If you add ffmpeg to your PATH it becomes available as ffmpeg regardless of what folder you're in, allowing the script to work as-is. This'll also make it easier for other people to run your script.

Running MacOS shortcuts shell command from node script

I am trying to run MacOS shortcuts via NodeJS script. To achieve that I created shortcuts in the MacOS Shortcuts app, which normally run in the terminal (ZSH) by typing shortcuts run shortcutname (Docs). They work fine when typing them directly into the terminal, but not when called from a NodeJS script.
My script looks like this:
exec('shortcuts run shortcutname', (error, stdout, stderr) => {
if (error) {
console.log(`error: ${error.message}`);
return;
}
if (stderr) {
console.log(`stderr: ${stderr}`);
return;
}
console.log(`stdout: ${stdout}`);
});
When starting the script from the terminal node script.js it does nothing. It does not return anything nor does it finish. I tried replacing the command shortcuts run shortcutname by other commands the system should know. For example ls, or git. They all work. Also when I leave out the shortcutname in the end, it complains about the missing parameter.
I was suspecting missing access rights, but apparently NodeJS runs as my normal user. Running whoami in script context returns my user name.
NODE_DEBUG=cluster,net,http,fs,tls,module,timers node script.js did not show anything unusual. I also tried using the full path of the binary. which shortcuts gave me /usr/bin/shortcuts. Which I used in my script /usr/bin/shortcuts run shortcutname.
What am I missing? Thanks in advance!
Though I thought I tested it, I found the solution:
execSync instead of exec works
It’d be cool if someone could explain why exec wouldn’t work.
Cheers!

How to execute a mongoDB shell script via Node.js?

I am working on my class project in which I want to demonstrate the use of mongoDB sharding. I am using mongoDB node.js native driver. I got to know there is no sharding functionality in this driver. So, I have to write shell script to do sharding. So, Is it possible to do this somehow like this:
node myfile.js (executes my shell script and run my code)
Given that you already have a shell script, why not execute that through the Child Process module. Just use the below function to run the script that you have.
child_process.execFileSync(file[, args][, options])
Note that the script should have run permissions(use chmod a+x script otherwise)
why don't you consider using npm run scripts?
if you want the script to run standalone, add scripts with test/start or both to your package json,
"scripts": {
"test": "node mytestfile.js",
"start": "node ./myfile --param1 --param2"
},
and run npm run test or npm run start which can execute the script file. this way you can even pass parameters to the script.
or the elegant child_process way,
const { exec } = require("child_process");
exec("node myfile.js", (error, stdout, stderr) => {
if (error) {
console.log(`error: ${error.message}`);
return;
}
if (stderr) {
console.log(`stderr: ${stderr}`);
return;
}
console.log(`stdout: ${stdout}`);
});
stderr and stdout will show the progress of the script as you build further.
hope this helps.

Unable to spawn a custom .exe from express.js on Windows

I am using node.js/express.js on windows and I have a command I execute when a user takes a image and uploads up from there phone. Once it is uploaded I run myApp.exe to perform some openCV image processing and I output the updated images to a output directory that is a argument in the command below.
I am able to kick this off from my webapp using child_process.exec, but the performance is 60x slower if I run it at command line by itself. To increase the performance I was hoping to use Spawn, but I don't know if this is an accurate assumption, please let me know if it is not.
var exec = require('child_process').exec;
var child = exec('C:\\opt\\package_v030_package\\myApp.exe
--user="C:\\opt\\package_v030_package\\Phone\\'+file.filename+'"
--mv="C:\\opt\\package_v030_package\\mv\\'+req.body.detectionString+'.bmp"
--outPath="C:\\opt\\package_v030_package\\output"
--outputScaled
--outputScaledOverlaid');
child.stdout.on('data', function(data) {
console.log('stdout: ' + data);
});
child.stderr.on('data', function(data) {
console.log('stdout: ' + data);
});
child.on('close', function(code) {
console.log('closing code: ' + code);
//res.json("success")
});
I have tried to kick it off using spawn, but it fails to execute with the following: "error child process exited with code 4294967295". The code is below:
var spawn = require('child_process').spawn;
var cmd = spawn('cmd', ['/s',
'/c',
'C:\\opt\\package_v030_package\\myApp.exe',
'--user="C:\\opt\\package_v030_package\\Phone\\'+file.filename+'"',
'--mv="C:\\opt\\package_v030_package\\mv\\'+req.body.detectionString+'.bmp"',
'--outPath="C:\\opt\\package_v030_package\\output"',
'--outputScaled',
'--outputScaledOverlaid'
]);
cmd.stdout.on('data', (data) => {
console.log(`stdout: ${data}`);
});
cmd.stderr.on('data', (data) => {
console.log(`stderr: ${data}`);
});
cmd.on('close', (code) => {
console.log(`child process exited with code ${code}`);
});
It seems I am able to execute just myApp.exe from spawn because when I add any of my arguments it fails. Even when I hard code the variables that I inject. Is there an issue with my arguments or am I spawning myApp.exe incorrectly?
Update 1
I placed the command in a .bat and was able to execute it from node.js using spawn. It does not increase performance which leads me to believe that the decrease in performance is a limitation of node.js on the windows platform.
In addition, I performed a few tests using postman to see if I could optimize the call without anything else happening, but I did not succeed. I will leave this question open in the event this changes and node.js is able to better handle performance of a CPU intensive child process.
Update 2 & Answer
I was able to fix this by placing the command that we run at the command line into a java class taking in the detectionString as a parameter. Then from node I use spawn to kick off the .jar file. This caused the speed to increase significantly and run as if I was running it myself at command line.
I was able to fix this by placing the command that we run at the command line into a java class taking in the detectionString as a parameter. Then from node I use spawn to kick off the .jar file. This caused the speed to increase significantly and run as if I was running it myself at command line.

executing node command from js file

I'm neewbe in writing node.js command line scripts. In my project we have a multi-app environment. To setup a dev env we need to launch 2 or more apps, so I'm wondering if it's possible to write a script which will do the following :
run a webpack --watch for my common project which will generate a bundle files
propagate bundles to the other apps.
launch webpack-dev-servers for others apps in separate terminals.
Is it possible to do that from a node script? At this moment I only achieved to implement the second step - a file propagation.
You can spawn a child process with node easily. So you could start multiple child processes from one file.
const exec = require('child_process').exec;
const child = exec('webpack --watch',
(error, stdout, stderr) => {
console.log(`stdout: ${stdout}`);
console.log(`stderr: ${stderr}`);
if (error !== null) {
console.log(`exec error: ${error}`);
}
});
Check the corresponding docs: https://nodejs.org/api/child_process.html#child_process_child_process_exec_command_options_callback

Resources