How to use wildcards in nodejs child_process.exec - node.js

Why does this not work? How to do it right?
var exec = require("child_process").exec;
exec("ls data/tile_0_{0..63}.jpg", function(error, stdout, stderr){
console.log('stdout: ' + stdout);
console.log('stderr: ' + stderr)}
);
// stdout:
// stderr: ls: cannot access data/tile_0_{0..63}.jpg: No such file or directory
In bash terminal this lists all files like tile_0_0.jpg, tile_0_1.jpg, etc.
This executed from node works as expected but does not do the thing I want.
ls data/tile_61_[0-9].jpg
Please help me ...
I'm using Linux Mint 14.

Why not do
var _ = require('underscore'),
fs = require('fs'),
files = fs.readdirSync('data');
var filtered = _.filter(files, function(filename){
return filename.indexOf('tile_0_') == 0;
});

Related

Automatic writing text to the console using Node.js

I need to clone GitHub repository using SSH and Node.js script:
var exec = require('child_process').exec;
exec('git clone git#github.com:jquery/jquery.git',
function (error, stdout, stderr) {
console.log('stdout: ' + stdout);
console.log('stderr: ' + stderr);
if (error !== null) {
console.log('exec error: ' + error);
}
}
);
If github.com not in known_hosts file, SSH forcing to enter "yes" on the question "Are you sure you want to continue connecting (yes/no)?".
How can I automate the input of this text?
P.S. I know about StrictHostKeyChecking=no, but I need to clone repository without changing SSH config.
Sure, that is entirely possible. When you call child_process.exec, it actually returns a ChildProcess Object. It contains an .stdin object which is an implementation of a Writable Stream, which you can pipe to / write to. Documentation on ChildProcess.stdin, also on Writable Stream.
Here is some example code that relates to your question:
var exec = require('child_process').exec;
var cmd = exec('git clone git#github.com:jquery/jquery.git', function (error, stdout, stderr) {
// ...
});
cmd.stdin.write("yes");
You could pass in yes prior to your git clone command.
exec('yes | git clone git#github.com:jquery/jquery.git'...

CasperJS/PhatomJS running shell commands

For the last few days I have been struggling with running shell commands from CasperJS/PhantomJS.
I am running simple unix sed on a file in node, which runs just fine:
var sys = require('sys')
var exec = require('child_process').exec;
var child;
// executes `sed`
child = exec("sed -i -e '1,1000d' file.name", function (error, stdout, stderr) {
sys.print('stdout: ' + stdout);
sys.print('stderr: ' + stderr);
if (error !== null) {
console.log('exec error: ' + error);
}
});
But whenever I run same with CasperJS, it just runs forever, not executing the shell command. Maybe someone could shed some light on this.
I did actually make it work through spawn and execFile functions from PhatomJS, but the issue is that it does not work with large files over 300MB.

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.

how to tail multiple files in node.js?

when use the following code to tail a file, we can successfully output data.
var spawn = require('child_process').spawn;
var filename = '/logs/error.log';
var tail = spawn("tail", ["-f", filename]);
tail.stdout.on("data", function (data) {
console.log(data);
});
but when i change filename to "/logs/*.log", i don't find anything output. who can tell me what is the reason? Thanks!
When typing tail -f /logs/*.log on the console, the expansion of /logs/*.log is handled by the shell; by the time the tail program gets the arguments, they've already been expanded to tail -f /logs/error.log /logs/other.log. You need to do the expansion yourself for Node:
var fs = require('fs');
var spawn = require('child_process').spawn;
var filename = fs.readdirSync('/logs').map(function(file) { return '/logs/' + file });
var tail = spawn("tail", ["-f"].concat(filename));
tail.stdout.on("data", function (data) {
console.log(data);
});
Because neither tail nor spawn know how to expand file names with wild cards into the set of matching file names. That's normally performed by the shell, so in this case you'll need to do it yourself in code.

Calling Make file in nested folder via Node.js

I have a complicated MakeFile file I want to call as part of my node.js app, the make file is a couple of directories deep from root. I know I need to spawn a 'make' chile process but moving node into the sub directory to call the make im not so sure about.
Сould you move the make to the nested folder? I would try something like
var util = require('util'),
exec = require('child_process').exec,
child;
child = exec('cd samples/nestedmake && make',
function (error, stdout, stderr) {
console.log('stdout: ' + stdout);
console.log('stderr: ' + stderr);
if (error !== null) {
console.log('exec error: ' + error);
}
});
(copied with minimal changes from Node Child Processes documentation).

Resources