How to run linux terminal commands on windows? - node.js

I'm not sure how to ask, but I'd like run the 'bash' command on windows 10 so that some linux commands run later. I'm using the framework Electron and the Child Process.
var os = require('os')
var exec = require('child_process').exec
if (os.platform() =='win32'){
var cmd_win = 'bash'
exec(cmd_win, function(error, stdout, stderr){
console.log(error)
});
}
The code snippet gives "Error: Command failed: bash". Does anyone know why? And can you help me? I hope you understood my question.

To initialize the WSL subsystem, you must launch a (hidden) Bash console window in the background, which doesn't work if you execute bash.exe directly - it works with neither exec nor execFile.
The trick is to get the shell (cmd) process that Node.js spawns to launch bash.exe without blocking, which, unfortunately, isn't easy to do: start cannot be used, because bash.exe is a console application and therefore makes start act synchronously.
The solution is to create an aux. VBScript file that launches bash.exe, which itself can be invoked asynchronously via wscript.exe. Note that the Bash console window is launched hidden:
var os = require('os')
var exec = require('child_process').exec
if (os.platform() === 'win32') {
var cmd_win = '\
echo WScript.CreateObject("Shell.Application").\
ShellExecute "bash", "", "", "open", 0 > %temp%\launchBashHidden.vbs \
& wscript %temp%\launchBashHidden.vbs'
exec(cmd_win, function(error, stdout, stderr){
if (error) console.error(error)
});
}
Note that the aux. VBScript file %temp%\launchBashHidden.vbs lingers between invocations. Cleaning it up after every run would require more work (you can't just delete it right away, because wscript, due to running asynchronously, may not have loaded it yet).

By default, exec will use cmd.exe to execute commands in windows. What you may be looking for is the shell option specified in the docs.
shell Shell to execute the command with (Default: '/bin/sh' on UNIX, 'cmd.exe' on Windows, The shell should understand the -c switch on UNIX or /s /c on Windows. On Windows, command line parsing should be compatible with cmd.exe.)
const os = require('os')
const exec = require('child_process').exec
if (os.platform() === 'win32') {
exec('ls', {shell: 'path/to/executable.exe'}, (err, stdout, stderr) => {
if (err) {
console.error(err)
return
}
console.log(stdout)
})
}

I have found a short way to do that that is :
Install git on your computer
Add C:\Program Files\Git\usr\bin to your path variable.
and check whether you can run linux commands in cmd.

Related

I want to run the terminal command n nodejs language

Creating a Nodejs server code, I'd like to turn on a new terminal window and enter a command.
var exec = require('child_process').exec
exec('gnome.terminal', (err,out,stderr) => {
console.log(out)
});`
I'd like to open a new window with the code above and enter a command.
(new) 1 terminal -> command : roslaunch rpliadr_ros rplidar.launch
(new) 2 terminal -> command : roslaunch hector_slam_launch tutorial.launch
Please look up shell.js module.
You can use OpenTerm module. It's do exactly what you want - open terminal, and execute.
It has both functions for individual terminals: ( consider to use them only if you sure they exists in your PATH ).
const { VT } = require('open-term')
VT.linux.xterm('ls -l') // Runs "ls -l" command in xterm.
VT.linux.guake('ls -l') // Runs "ls -l" command in guake.
And configurable function which automatically determines terminal to use:
const { VTexec } = require('open-term')
VTexec('help') // "help" command works both on bash and cmd.

How to pass or output data from a ruby script to a node.js script?

I am looking for a way to pass or output data from one script to another script so that the late script can execute itself with the output that came from the first one.
Basically, I have a ruby script with some instructions in it and I want to pass (or output...) the result of the ruby script to a node.js script.
I would like help ( and examples ... ) on how to realize this and/or recommendations for techniques or technologies I might have never heard of it that might do the trick
Thank you.
You can use child_process exec to execute a script and handle it's output.
Ruby Script
# example.rb
puts "hello world"
Node Script
// example.js
const exec = require('child_process').exec
exec('ruby example.rb', function(err, stdout, stderr) {
console.error(err)
console.error('stderr: ' + stderr)
console.log('stdout: ' + stdout) // logs "hello world"
});

Pass REST API data back to Node command line

I’m running this command:
NODE_ENV=production grunt babel && NODE_ENV=sandbox node dist/bin/copilot.js --mode $1
copilot.js launches another JavaScript file (depending on what the mode argument is in line above); in this case it’s copilotMonitor.js
The short story is this ‘Monitor’ pings a REST API record, data is returned to it on if a mode needs to be restarted. The API will return something to copilotMonitor.js along the lines of "mode_3".
How can I then pass this command pkill -9 -f <mode> back to the command line?
I know process.argv tells me what arguments I passed into the node application, but I’d like to pass stuff back to the node app, if that makes sense.
Answer, Node Child Process!
https://nodejs.org/docs/latest-v4.x/api/child_process.html#child_process_child_process_exec_command_options_callback
I also found this video helpful: https://www.youtube.com/watch?v=9o8B3L0-d9c
const exec = require('child_process').exec;
exec(`pkill -9 -f ${mode}`, (err, stdout, stderr) => {
if (err) {
console.log(`There was an error killing mode ${mode}`);
console.error('error: ', err);
return;
}
console.log('kill restart! stdout: ', mode, stdout)
console.log('kill restart! stderr: ', mode, stderr)
});

NodeJs spawn giving ENOENT error (Raspbian)

i'm having an error regarding spawning nodeJs script:
exec('node ./modules/buttons', function(error, stdout, stderr) {
if(error) console.log(error);
console.log(stdout);
if(stderr) console.log(stderr);
});
Exec Works perfectly fine. However spawn
var buttons = spawn('node ./modules/buttons.js', []);
buttons.stdout.on('data', function(data){
console.log(data);
});
Gives me the following error:
spawn node ./modules/buttons.js ENOENT
Defining the absolute path to the script results in the same error. Would appreciate it if someone could help me resolving this; I have absolutely no clue what could be the cause of this and google isn't helping me either.
exec accepts the command to be executed along with all the command line parameters, but spawn, OTOH, accepts the program to invoke and the command line arguments as an array.
In your case, Node.js is trying to execute a program called node ./modules/buttons.js, not node with ./modules/buttons.js as command line argument. That is why it is failing.
Quoting the example from the spawn docs,
const spawn = require('child_process').spawn;
const ls = spawn('ls', ['-lh', '/usr']);
The difference between exec and spawn is that, exec will be default launch the command in a shell, spawn simply invokes the program.
Note: BTW, as you are simply invoking a JavaScript file, you are better off using execFile

fetching 'rsync' output with nodejs child_process.exec callback

Currently I'm failing to fetch the rsync output when I'm calling nodejs child_process.exec with a callback-function like in this snippet:
var sys = require('sys'),
exec = require('child_process').exec;
cmd = 'rsync -rpz test/test-files/one.txt jloos#test.mygnia.de:~/remote-test/a/b/'
exec(cmd, function(error, stdio, stderr) {
sys.print('s: ' + stdio + '\n');
sys.print('e: ' + stderr + '\n');
});
I think this is caused by the specific behavior of rsync. rsync communicates with it's counterpart via terminal. So how can I fetch the messages from rsync, if even possible?
When I use cmd = 'ls -la' I get the expected output.
Thanks
Often stdout is buffered when the program isn't running in a virtual terminal.
Many languages have a pty module which will trick the program into behaving as though it is running in a terminal.
This provides that functionality for NodeJs;
https://github.com/chjj/pty.js
Keep in mind that rsync may be writing lots of special characters or using something like ncurses to provide the updating status messages, which may make it more difficult to work with the output.

Resources