我正在将一个CLI库从Ruby移植到Node.js。在我的代码中,必要时我会执行几个第三方二进制文件。我不确定如何在Node中实现这一点。

下面是Ruby中的一个示例,我调用PrinceXML将文件转换为PDF:

cmd = system("prince -v builds/pdf/book.html -o builds/pdf/book.pdf")

Node中的等效代码是什么?


当前回答

由于版本4,最接近的替代方法是child_process.execSync方法:

const {execSync} = require('child_process');

let output = execSync('prince -v builds/pdf/book.html -o builds/pdf/book.pdf');

⚠️ 请注意,execSync调用会阻塞事件循环。

其他回答

const exec = require("child_process").exec
exec("ls", (error, stdout, stderr) => {
 //do whatever here
})

@六氰的答案几乎是完整的。在Windows命令prince可以是prince.exe、prince.cmd、prince.bat或prince(我不知道gems是如何绑定的,但npm bin附带了sh脚本和批处理脚本-npm和npm.cmd)。如果你想编写一个在Unix和Windows上运行的可移植脚本,你必须生成正确的可执行文件。

这里有一个简单但可移植的派生函数:

function spawn(cmd, args, opt) {
    var isWindows = /win/.test(process.platform);

    if ( isWindows ) {
        if ( !args ) args = [];
        args.unshift(cmd);
        args.unshift('/c');
        cmd = process.env.comspec;
    }

    return child_process.spawn(cmd, args, opt);
}

var cmd = spawn("prince", ["-v", "builds/pdf/book.html", "-o", "builds/pdf/book.pdf"])

// Use these props to get execution results:
// cmd.stdin;
// cmd.stdout;
// cmd.stderr;

现在,可以按如下方式使用shelljs(从节点v4):

var shell = require('shelljs');

shell.echo('hello world');
shell.exec('node --version');

使用安装

npm install shelljs

看见https://github.com/shelljs/shelljs

如果你想要一个与顶级答案非常相似但同时也是同步的答案,那么这将起作用。

var execSync = require('child_process').execSync;
var cmd = "echo 'hello world'";

var options = {
  encoding: 'utf8'
};

console.log(execSync(cmd, options));

节点JS v15.8.0、LTS v14.15.4和v12.20.1——2021 2月

异步方法(Unix):

'use strict';

const { spawn } = require( 'child_process' );
const ls = spawn( 'ls', [ '-lh', '/usr' ] );

ls.stdout.on( 'data', ( data ) => {
    console.log( `stdout: ${ data }` );
} );

ls.stderr.on( 'data', ( data ) => {
    console.log( `stderr: ${ data }` );
} );

ls.on( 'close', ( code ) => {
    console.log( `child process exited with code ${ code }` );
} );

异步方法(Windows):

'use strict';

const { spawn } = require( 'child_process' );
// NOTE: Windows Users, this command appears to be differ for a few users.
// You can think of this as using Node to execute things in your Command Prompt.
// If `cmd` works there, it should work here.
// If you have an issue, try `dir`:
// const dir = spawn( 'dir', [ '.' ] );
const dir = spawn( 'cmd', [ '/c', 'dir' ] );

dir.stdout.on( 'data', ( data ) => console.log( `stdout: ${ data }` ) );
dir.stderr.on( 'data', ( data ) => console.log( `stderr: ${ data }` ) );
dir.on( 'close', ( code ) => console.log( `child process exited with code ${code}` ) );

同步:

'use strict';

const { spawnSync } = require( 'child_process' );
const ls = spawnSync( 'ls', [ '-lh', '/usr' ] );

console.log( `stderr: ${ ls.stderr.toString() }` );
console.log( `stdout: ${ ls.stdout.toString() }` );

来自Node.js v15.8.0文档

Node.js v14.15.4文档和Node.js v12.20.1文档也是如此