Node.js 使用child_process.execSync,但将输出保留在控制台中

Node.js 使用child_process.execSync,但将输出保留在控制台中,node.js,child-process,Node.js,Child Process,我想使用NodeJS 0.12中添加的execSync方法,但在运行节点脚本的控制台窗口中仍然有输出 例如,如果我运行具有以下行的NodeJS脚本,我希望在控制台内看到rsync命令“live”的完整输出: require('child_process').execSync('rsync -avAXz --info=progress2 "/src" "/dest"'); 我知道,execSync返回命令的输出,我可以在执行后将其打印到控制台,但这样我就没有“实时”输出…除非您按照公认的答案重定

我想使用NodeJS 0.12中添加的
execSync
方法,但在运行节点脚本的控制台窗口中仍然有输出

例如,如果我运行具有以下行的NodeJS脚本,我希望在控制台内看到rsync命令“live”的完整输出:

require('child_process').execSync('rsync -avAXz --info=progress2 "/src" "/dest"');

我知道,
execSync
返回命令的输出,我可以在执行后将其打印到控制台,但这样我就没有“实时”输出…

除非您按照公认的答案重定向stdout和stderr,否则execSync或spawnSync不可能做到这一点。在不重定向stdout和stderr的情况下,这些命令仅在命令完成时返回stdout和stderr

要在不重定向stdout和stderr的情况下执行此操作,您需要使用spawn来执行此操作,但这非常简单:

var spawn = require('child_process').spawn;

//kick off process of listing files
var child = spawn('ls', ['-l', '/']);

//spit stdout to screen
child.stdout.on('data', function (data) {   process.stdout.write(data.toString());  });

//spit stderr to screen
child.stderr.on('data', function (data) {   process.stdout.write(data.toString());  });

child.on('close', function (code) { 
    console.log("Finished with code " + code);
});
我使用了一个ls命令,该命令递归地列出文件,以便您可以快速测试它。Spawn将您尝试运行的可执行文件名作为第一个参数,并将表示要传递给该可执行文件的每个参数的字符串数组作为第二个参数

但是,如果设置为使用execSync,并且由于某种原因无法重定向stdout或stderr,则可以打开另一个终端,如xterm,并向其传递如下命令:

var execSync = require('child_process').execSync;

execSync("xterm -title RecursiveFileListing -e ls -latkR /");
这将允许您查看您的命令在新终端中执行的操作,但仍有同步调用。

如果您需要,您可以传递:

require('child_process').execSync(
    'rsync -avAXz --info=progress2 "/src" "/dest"',
    {stdio: 'inherit'}
);

您只需使用
.toString()

var result=require('child_process').execSync('rsync-avAXz--info=progress2”/src”“/dest”“).toString();
控制台日志(结果);
这已经在Node
v8.5.0
上测试过,我不确定以前的版本。根据,它在
v6.3.1
上不起作用-我不确定介于两者之间


编辑:回顾这一点,我意识到它实际上并没有回答特定的问题,因为它不会“实时”地向您显示输出——只有在命令完成运行后才会显示

但是,我将这个答案留在这里,因为我知道很多人遇到这个问题,只是想知道如何在执行后打印命令的结果。

简单地说:

 try {
    const cmd = 'git rev-parse --is-inside-work-tree';
    execSync(cmd).toString();
 } catch (error) {
    console.log(`Status Code: ${error.status} with '${error.message}'`;
 }
参考:

命令成功运行时:

这意味着子进程将使用父进程的stdin、stdout和stderr流。因此,当子进程写入它们中的任何一个时,它实际上将直接写入父进程的流。这是一个非常有价值的答案,因为官方文档并没有真正明确说明预期的语法。我使用了
[0,1,2]
而不是
'inherit'
,这相当于
[process.stdin,process.stdout,process.stderr]
[0,1,2]
根据
选项的正确链接。stdio
文档:@Booligoosh而不是简单地添加
{stdio:'inherit'}
,您必须添加.toString()然后用结果手动调用console.log。此外,它甚至不能满足查看命令输出“live”的问题要求。我认为这“简单得多”,事实上,我并不认为这更简单。使用spawn的示例可能是正确的,但关于不打算使用execSync的开头陈述并不准确。请参阅@gregersThis的答案。这在失败时不起作用(状态代码!=0),因为
.execSync()抛出<代码>错误< /代码>实例。它不适用于命令完成后的输出。这是否适用于特定版本?我的节点-V:V3.3.1请考虑更新答案,注意它仅适用于某些节点版本。这将使它对其他的投票更加有用,因为TI现在与T相关。o执行命令期间有关输出的问题。
// nodejs
var execSync = require('child_process').execSync;

// typescript
const { execSync } = require("child_process");

 try {
    const cmd = 'git rev-parse --is-inside-work-tree';
    execSync(cmd).toString();
 } catch (error) {
    error.status;  // 0 : successful exit, but here in exception it has to be greater than 0
    error.message; // Holds the message you typically want.
    error.stderr;  // Holds the stderr output. Use `.toString()`.
    error.stdout;  // Holds the stdout output. Use `.toString()`.
 }