echo忽略child_process.exec()中的标志

时间:2014-11-12 23:15:31

标签: node.js

当我直接在bash中输入echo -n foo时,它会按预期工作并打印foo而不会有任何尾随的新行。

但是,我已经编写了以下代码来使用child_process.exec()方法打印一些文本;

var exec = require('child_process').exec;
exec("echo -n foo",
    function(error, stdout, stderr) {
        console.log(stdout);
    }
);

但是,-n标记无法按预期工作,并打印-n foo后跟一个空行。

更新:我发现问题只发生在OS X上,我在Ubuntu上尝试了相同的脚本,并且按预期工作。

2 个答案:

答案 0 :(得分:4)

对于我来说,它至少适用于Linux上的节点v0.10.30。

此:

var exec = require('child_process').exec;
exec('echo -n foo', function(error, stdout, stderr) {
  console.dir(stdout);
});

输出:

'foo'

但是,在Windows上,您描述的行为确实存在,但这是因为Windows'echo命令与* nix上的命令不同(因此它与命令后面的内容完全相同)。

它在OS X上也不起作用的原因是(来自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.

当您致电exec()时,节点会在* nix平台上生成/bin/sh -c "<command string>"。因此(如手册页中所述)OS X上的/bin/sh不支持echo -n,这会导致您看到的输出。但是它可以在终端上运行,因为该用户的默认shell不是/bin/sh,而是/bin/bash 支持echo -n。它也适用于Linux,因为大多数系统都/bin/sh指向/bin/bash或其他支持echo -n的shell。

所以解决方案是更改命令以强制使用echo二进制文件而不是内置shell echo

var exec = require('child_process').exec;
exec('`which echo` -n foo', function(error, stdout, stderr) {
  console.dir(stdout);
});

或像这样使用spawn()

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

或者如果您想继续使用exec()而不更改代码,请将/bin/sh符号链接设为/bin/bash

答案 1 :(得分:0)

JavaScript console.log函数将\n换行符添加到字符串中。如果要打印没有换行符的字符串,可以这样做:

var exec = require('child_process').exec;
exec("echo -n foo",
    function(error, stdout, stderr) {
        process.stdout.write(stdout);
    }
);