Reputation: 43
When I type echo -n foo
directly in bash, it works as expected and prints foo
without any trailing new lines.
But, I've written the following code to print some text using child_process.exec() method;
var exec = require('child_process').exec;
exec("echo -n foo",
function(error, stdout, stderr) {
console.log(stdout);
}
);
However, the -n
flag doesn't work as expected and it prints -n foo
followed by a blank line.
UPDATE: I figured out that problem occurs only on OS X, I've tried the same script on Ubuntu and it works as expected.
Upvotes: 3
Views: 2635
Reputation: 106746
It works fine for me with at least node v0.10.30 on Linux.
This:
var exec = require('child_process').exec;
exec('echo -n foo', function(error, stdout, stderr) {
console.dir(stdout);
});
outputs:
'foo'
However, on Windows the behavior you describe does exist, but that is because Windows' echo
command is not the same as on *nix (and so it echoes exactly what came after the command).
The reason it also does not work on OS X is because (from man echo
):
Some shells may provide a builtin echo command which is similar or iden- tical to this utility. Most notably, the builtin echo in sh(1) does not accept the -n option.
When you call exec()
, node spawns /bin/sh -c "<command string>"
on *nix platforms. So (as noted in the man page) /bin/sh
on OS X does not support echo -n
, which results in the output you're seeing. However it works from the terminal because the default shell for that user is not /bin/sh
but likely /bin/bash
, which does support echo -n
. It also works on Linux because most systems have /bin/sh
pointing to /bin/bash
or some other shell that supports echo -n
.
So the solution is to change the command to force the use of the echo
binary instead of the built-in shell's echo
:
var exec = require('child_process').exec;
exec('`which echo` -n foo', function(error, stdout, stderr) {
console.dir(stdout);
});
or use spawn()
like this:
var spawn = require('child_process').spawn,
p = spawn('echo', ['-n', 'foo']),
stdout = '';
p.stdout.on('data', function(d) { stdout += d; });
p.stderr.resume();
p.on('close', function() {
console.dir(stdout);
});
or if you want to keep using exec()
without changing the code, then make /bin/sh
a symlink to /bin/bash
.
Upvotes: 5
Reputation: 2945
The JavaScript console.log
function appends a \n
newline character to a string. If you want to print a string without a newline character, you can do it like this:
var exec = require('child_process').exec;
exec("echo -n foo",
function(error, stdout, stderr) {
process.stdout.write(stdout);
}
);
Upvotes: -1