how do I make node child_process exec continuously - node.js

How to exec continuously? e.g. ls after cd?
I tried
exec = require('child_process').exec;
exec('cd ~/',
function(){
exec('ls'),
function(err, stdout, stderr){
console.log(stdout); // this logs current dir but not ~/'s
}
}
)
exec('cd ~/').exec('ls', function(err, stdout, stderr){
console.log(stdout);
})//this also fails because first exec returns a ChildProcess Object but not itself.

It is not possible to do this because exec and spawn creates a new process. But there is a way to simulate this. You can start a process with exec and execute multiple commands in the same time:
In the command line if you want to execute 3 commands on the same line you would write:
cmd1 & cmd2 & cmd3
So, all 3 commands run in the same process and have access to the context modified by the previous executed commands.
Let's take your example, you want to execute cd ../ and after that to execute dir and to view the previous directory list.
In cmd you shoud write:
cd../ & dir
From node js you can start a process with exec and to tell it to start another node instance that will evaluate an inline script:
var exec = require('child_process').exec;
var script = "var exec = require('child_process').exec;exec('dir',function(e,d,er){console.log(d);});";
script = '"'+script+'"';//enclose the inline script with "" because it contains spaces
var cmd2 = 'node -e '+script;
var cd = exec('cd ../ &'+cmd2,function(err,stdout,strerr)
{
console.log(stdout);//this would work
})
If you just want to change the current directory you should check the documentation about it http://nodejs.org/api/child_process.html#child_process_child_process_exec_command_options_callback

You can use nodejs promisify and async/await:
const { promisify } = require('util');
const exec = promisify(require('child_process').exec);
export default async function () {
const cpu = await exec('top -bn1');
const disk = await exec('df -h');
const memory = await exec('free -m');
const payload = {
cpu,
disk,
memory,
};
return payload
}

If you want to use cd first, better use process.chdir('~/'). Then single exec() will do the job.

You can call exec with cwd param like so:
exec('ls -a', {
cwd: '/Users/user'
}, (err, stdout) => {
if (err) {
console.log(err);
} else {
console.log(stdout);
}
})
But beware, cwd doesn't understand '~'. You can use process.env.HOME instead.

Related

Open terminal and launch commands

In my electron/reactjs app, i'm trying to open a terminal and launch somes commands.
My code looks like this :
const terminal = 'x-terminal-emulator';
const { spawn } = require('child_process');
spawn(terminal);
My terminal opens but i don't know how to launch commands in this terminal like 'cd /my/custom/path && ls'
Can someone help me please ? :)
Node.js child_process.spawn command have an option to specify the shell you want to use.
So I would use the opposite logic and launch directly the command within a particular shell (for exemple bash):
const { spawn } = require('child_process');
const terminal = '/bin/bash';
let cmd = 'echo $SHELL';
spawn(cmd, { shell: terminal })
.stdout.on('data', (data) => {
console.log(`stdout: ${data}`); //-> stdout: /bin/bash
});

Changing command prompt directory from Node.js script

I'm trying to change the directory of terminal using with Node.js program but not able to achieve it. Script is run as node app.js dir_name so first I'm creating the directory and then trying to change into that directory using cd command. Directory is created but the directory for terminal is not changed.
#!/usr/bin/env node
var platform = process.platform;
var figlet = require('figlet');
var chalk = require('chalk');
if(process.argv.length < 3){
console.log(
chalk.green(
figlet.textSync('mdcd', { horizontalLayout: 'full' })
)
);
console.log(chalk.red("Please provide a directory name"));
}else{
if(platform.includes("win")){
//console.log("Its Windows");
}else {
var exec = require('child_process').exec;
var command_1 = "mkdir "+process.argv[2];
var command_2 = "cd "+process.cwd()+"/"+process.argv[2];
exec(command_1, function (error, stdout, stderr) {
if(error){
console.log("Something bad happened"+error);
}else {
exec(command_2, function (error, stdout, stderr) {
if(error){
console.log("Something bad happened"+error);
}
});
}
});
}
}
command prompt directory from Node.js script
You cannot change the command prompt directory. Basically you have the process tree:
cmd / term
| -> NodeJs
You shouldn't change the working dir for cmd. However there are command you can execute to change the working dir of any process e.g. https://unix.stackexchange.com/a/282009
More
You can however change the the working dir for the nodejs process (which is what I suspect you want to do) using process.chdir https://nodejs.org/api/process.html#process_process_chdir_directory

How to run shell script file using nodejs?

I need to run a shell script file using nodeJS that executes a set of Cassandra DB commands. Can anybody please help me on this.
inside db.sh file:
create keyspace dummy with replication = {'class':'SimpleStrategy','replication_factor':3}
create table dummy (userhandle text, email text primary key , name text,profilepic)
You could use "child process" module of nodejs to execute any shell commands or scripts with in nodejs. Let me show you with an example, I am running a shell script(hi.sh) with in nodejs.
hi.sh
echo "Hi There!"
node_program.js
const { exec } = require('child_process');
var yourscript = exec('sh hi.sh',
(error, stdout, stderr) => {
console.log(stdout);
console.log(stderr);
if (error !== null) {
console.log(`exec error: ${error}`);
}
});
Here, when I run the nodejs file, it will execute the shell file and the output would be:
Run
node node_program.js
output
Hi There!
You can execute any script just by mentioning the shell command or shell script in exec callback.
You can execute any shell command using the shelljs module
const shell = require('shelljs')
shell.exec('./path_to_your_file')
you can go:
var cp = require('child_process');
and then:
cp.exec('./myScript.sh', function(err, stdout, stderr) {
// handle err, stdout, stderr
});
to run a command in your $SHELL.
Or go
cp.spawn('./myScript.sh', [args], function(err, stdout, stderr) {
// handle err, stdout, stderr
});
to run a file WITHOUT a shell.
Or go
cp.execFile();
which is the same as cp.exec() but doesn't look in the $PATH.
You can also go
cp.fork('myJS.js', function(err, stdout, stderr) {
// handle err, stdout, stderr
});
to run a javascript file with node.js, but in a child process (for big programs).
EDIT
You might also have to access stdin and stdout with event listeners. e.g.:
var child = cp.spawn('./myScript.sh', [args]);
child.stdout.on('data', function(data) {
// handle stdout as `data`
});
Also, you can use shelljs plugin.
It's easy and it's cross-platform.
Install command:
npm install [-g] shelljs
What is shellJS
ShellJS is a portable (Windows/Linux/OS X) implementation of Unix
shell commands on top of the Node.js API. You can use it to eliminate
your shell script's dependency on Unix while still keeping its
familiar and powerful commands. You can also install it globally so
you can run it from outside Node projects - say goodbye to those
gnarly Bash scripts!
An example of how it works:
var shell = require('shelljs');
if (!shell.which('git')) {
shell.echo('Sorry, this script requires git');
shell.exit(1);
}
// Copy files to release dir
shell.rm('-rf', 'out/Release');
shell.cp('-R', 'stuff/', 'out/Release');
// Replace macros in each .js file
shell.cd('lib');
shell.ls('*.js').forEach(function (file) {
shell.sed('-i', 'BUILD_VERSION', 'v0.1.2', file);
shell.sed('-i', /^.*REMOVE_THIS_LINE.*$/, '', file);
shell.sed('-i', /.*REPLACE_LINE_WITH_MACRO.*\n/, shell.cat('macro.js'), file);
});
shell.cd('..');
// Run external tool synchronously
if (shell.exec('git commit -am "Auto-commit"').code !== 0) {
shell.echo('Error: Git commit failed');
shell.exit(1);
}
Also, you can use from the command line:
$ shx mkdir -p foo
$ shx touch foo/bar.txt
$ shx rm -rf foo

How to out output live console.log with exec in node

Is there a way to run a command line command from within a node app and get the output to be live?
eg:
var exec = require('child_process').exec;
var fs = require('fs');
exec( 'nightwatch --config nightwatch_dev.json ', function( error, stdout, stderr ){
console.log( stdout );
});
or:
var exec = require('child_process').exec;
var fs = require('fs');
exec( 'rsync -avz /some/folder/ john#8.8.8.8:/some/folder/', function( error, stdout, stderr ){
console.log( stdout );
});
There are many many instances where it would be nice and easy to script something up in node but the output is only dumped to the terminal after the command has finished.
Cheers
J
If you want results as they occur, then you should use spawn() instead of exec(). exec() buffers the output and then gives it to you all at once when the process has finished. spawn() returns an event emitter and you get the output as it happens.
Examples here in the node.js doc for .spawn():

How to get the cwd (current working directory) from a nodejs child process (in both windows and linuxish)

I'm trying to run a script via nodejs that does:
cd ..
doSomethingThere[]
However, to do this, I need to executed multiple child processes and carry over the environment state between those processes. What i'd like to do is:
var exec = require('child_process').exec;
var child1 = exec('cd ..', function (error, stdout, stderr) {
var child2 = exec('cd ..', child1.environment, function (error, stdout, stderr) {
});
});
or at very least:
var exec = require('child_process').exec;
var child1 = exec('cd ..', function (error, stdout, stderr) {
var child2 = exec('cd ..', {cwd: child1.process.cwd()}, function (error, stdout, stderr) {
});
});
How can I do this?
to start child with parent dir as cwd:
var exec = require('child_process').exec;
var path = require('path')
var parentDir = path.resolve(process.cwd(), '..');
exec('doSomethingThere', {cwd: parentDir}, function (error, stdout, stderr) {
// if you also want to change current process working directory:
process.chdir(parentDir);
});
Update: if you want to retrieve child's cwd:
var fs = require('fs');
var os = require('os');
var exec = require('child_process').exec;
function getCWD(pid, callback) {
switch (os.type()) {
case 'Linux':
fs.readlink('/proc/' + pid + '/cwd', callback); break;
case 'Darwin':
exec('lsof -a -d cwd -p ' + pid + ' | tail -1 | awk \'{print $9}\'', callback);
break;
default:
callback('unsupported OS');
}
}
// start your child process
// note that you can't do like this, as you launch shell process
// and shell's child don't change it's cwd:
// var child1 = exec('cd .. & sleep 1 && cd .. sleep 1');
var child1 = exec('some process that changes cwd using chdir syscall');
// watch it changing cwd:
var i = setInterval(getCWD.bind(null, child1.pid, console.log), 100);
child1.on('exit', clearInterval.bind(null, i));
If you want to get the current working directory without resorting to OS specific command line utilities, you can use the "battled-tested" shelljs library that abstract these things for you, while underneath using child processes.
var sh = require("shelljs");
var cwd = sh.pwd();
There you have it, the variable cwd holds your current working directory whether you're on Linux, Windows, or freebsd.
Just a thought, if you know the child process's PID, and have pwdx installed (likely on linux), you could execute that command from node to get the child's cwd.
I think the best bet is manipulating the options.cwd between calls to exec. in exec callback this.pwd and this.cwd might give you leverage for your implementations.

Resources