Cannot Launch `gksudo` using NodeJs `exec` - node.js

Goal
I want to show graphical password prompt in nodejs to elevate priviledge thus gain some power to copy file content into another, but the last is owned by root.
In the implementation, I try to execute dd along with it's argument with gksudo with exec() function.
exec = require('child_process').exec
printall = function (error, stdout, stderr) {
console.log('stdout: ' + stdout);
console.log('stderr: ' + stderr);
if (error) {
console.log('exec err: ' + error);
}
}
exec("gksudo dd if=/home/user/minor.txt of=/home/user/major.txt", printall)
Error
But I always fail, with no good reason.
It said,
stdout:
stderr:
exec err: Error: Command failed: /bin/sh -c gksudo dd if=/home/user/minor.txt of=/home/user/major.txt
If I reproduce the command into terminal, it missed double quotes and instead run gksudo only. Well, in nodejs, it simply fails.
Notes
I originally develop Atom package. It's my first time, so, I found out about a different version of Node (or IOJs?). I execute the whole code inside Atom.
Question
If you expect a clear question, well, possibly
How to execute gksudo within node.js to run other command along with the arguments?

Related

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)
});

How to run linux terminal commands on windows?

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.

Execute multiple commands in Third party CLI mode using Node JS

I want to execute 5 commands in a sequence and log its output.For Example. First command XXXcli ip_address (This will connect me to the third party CLI mode) and the next commands will execute a script,the next will log output etc.But my problem is when I do SSH through node.js and spawn a shell inside ssh session, when I execute the first command I couldn't see any output on my Console. The Session creates a shell and once the shell enters the third party CLI ,Its becoming impossible for me to fire the next command or log the output of the first command.Kindly help me on this. I'm stuck with this for a long time
Update:
My Code:
session.on('exec', function (accept, reject, info) {
console.log('Client wants to execute: ' + inspect(info.command));
var stream = accept();
var cp = spawn('XXXCLI 10.21.254.12', {shell: true});
stream.stdin.pipe(cp.stdin);
cp.stdout.pipe(stream.stdout);
sleep(6000);
cp.stderr.pipe(stream.stderr);
cp.on('exit', function (code, signal) {
stream.exit(signal || code);
}).on('end', function (code, signal) {
stream.close();
});
});
When I manually type the first command 'XXXCLI ip_address' in my command prompt and press enter,I will get a output "Connected to CLI...." .Once I get this connection successful, I need to execute my second command i.e "Lmc sample" which will load the master config and I will get the output as "Message sent..", third command will execute a script,will get output as "Message sent.." .This is what happens when I enter these commands manually in cmd prompt and execute.
What is happening is once I execute my first command i.e "XXXCLI 10.21.254.12" manually in cmd, The path where we actually execute the commands i.e( C:\users\CLI>) will not be visible. This happens because now it got connected with the above mentioned ip (10.21.254.12) .And Only after connecting to this ip ,I can able to execute my other commands.i.e command to load master config ,cmd to execute script etc.
So I want to execute my first command and get its stream in a variable and execute rest of the commands inside the stream created by first command
Thanks!
I fixed this using Child Process in Node.js and writing the commands in the stream directly. When I did the same with Java it didn't work, but it did in Node.js.

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.

Making lftp write to stdout without having to close the process first

I'm trying to wrap the lftp program in a node.js application, using child_process. The problem is that lftp doesn't write its output to stdout, so I cannot catch its output in node.js. Sample code:
var proc = require('child_process').spawn('lftp', ['-p', port, '-u', username + ',' + password, host]);
proc.stdout.on('data', function (data) {
console.log('stdout:', data.toString('utf-8'));
});
proc.on('exit', function (code) {
console.log('process exited with code ' + code);
});
proc.stdin.write('ls');
// proc.stdin.end();
If I uncomment the line that calls stdin.end() for the lftp child process, the output from the ls command appears in my terminal as it should. If I don't the process simply hangs and nothing gets outputted.
I've also tried using unbuffer, but it doesn't seem to allow me to write to lftp's stdin anymore. It outputs the usual "[Resolving host address...]" stuff, but not the output from the ls command.
My question is: what do I have to do to be able to interact with lftp using node.js' child_process?
Well, this was dumb. I forgot to write a newline after the ls command to stdin. It seems to work without the need for unbuffer.

Resources