使用child_process.execSync但在控制台中保持输出

sua*_*kim 132 child-process node.js

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

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

require('child_process').execSync('rsync -avAXz --info=progress2 "/src" "/dest"');
Run Code Online (Sandbox Code Playgroud)

我明白execSync返回命令的输出,我可以在执行后将其打印到控制台,但这样我没有"实时"输出...

gre*_*ers 273

您可以将父级的stdio传递给子进程,如果这是您想要的:

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

  • 而不是`[0,1,2]`我使用''inherit'`,相当于`[process.stdin,process.stdout,process.stderr]`或`[0,1,2]`根据[docs](https://nodejs.org/api/child_process.html) (45认同)
  • 正确链接到`options.stdio`文档:https://nodejs.org/api/child_process.html#child_process_options_stdio (8认同)
  • 这是一个非常有价值的答案,因为官方文档并没有真正明确预期的语法. (6认同)
  • 这意味着子进程将使用父进程的stdin,stdout和stderr流.因此,当子进程写入其中任何一个时,它实际上将直接写入父进程流. (3认同)
  • stdio[0,1,2] 是什么意思? (2认同)
  • @Booligoosh而不是简单地添加`{stdio:'inherit'}`,您必须添加.toString(),然后使用结果手动调用console.log。此外,它甚至不能满足看到“实时”命令输出的问题要求。我不认为它“简单得多”,实际上我并不认为它更简单。 (2认同)

Eth*_*han 16

你可以简单地使用.toString().

var result = require('child_process').execSync('rsync -avAXz --info=progress2 "/src" "/dest"').toString();
console.log(result);
Run Code Online (Sandbox Code Playgroud)

这已在Node上测试过v8.5.0,我不确定以前的版本.根据@etov,它不起作用v6.3.1- 我不确定中间.

  • 这不适用于失败(状态代码!= 0),因为`.execSync()`抛出一个`Error`实例. (3认同)
  • 投反对票,因为 ti 现在与执行命令期间的输出问题有关。 (2认同)

Bri*_*ian 14

除非您按照接受的答案建议重定向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);
});
Run Code Online (Sandbox Code Playgroud)

我使用了一个递归列出文件的ls命令,以便您可以快速测试它.Spawn将您尝试运行的可执行文件名作为第一个参数,因为它是第二个参数,它采用一个字符串数组来表示要传递给该可执行文件的每个参数.

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

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

execSync("xterm -title RecursiveFileListing -e ls -latkR /");
Run Code Online (Sandbox Code Playgroud)

这将允许您查看您的命令在新终端中正在执行的操作但仍具有同步调用.

  • 使用spawn的示例可能是正确的,但关于不使用execSync的开头语句并不准确.请参阅@gregers的回答 (2认同)

uza*_*y95 9

简单地:

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

参考:/sf/answers/3015454221/

// 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()`.
 }
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

在此输入图像描述

当命令运行成功时: 在此输入图像描述