9

node.js vm 模块中,我可以在另一个 node.js 进程中执行一些 javascript。我想要实现的是能够捕获在 vm 运行的脚本中执行的日志。

例如,我想捕获“foobar”日志:

var vm = require('vm')

vm.runInThisContext('console.log("foobar");', 'myfile.vm');

// how can i get the "foobar" log?

提前致谢

编辑:下面的答案效果很好,虽然有一个较短的版本:

function captureStdout(callback) {
    var output = '', old_write = process.stdout.write

    // start capture
    process.stdout.write = function(str, encoding, fd) {
        output += str
    }

    callback()

    // end capture
    process.stdout.write = old_write

    return output
}
4

3 回答 3

5

您可以直接包装console.log:

function hook_consolelog(callback) {
    var old_log = console.log;

    console.log = (function(write) {
        return function() {
            write.apply(console, arguments)
            callback.apply(null, arguments);
        }
    })(console.log)

    return function() {
        console.log = old_log;
    }
}

var result;
var unhook = hook_consolelog(function(v) {
    result = v;
});

console.log('hello');
unhook();
console.log('goodbye');
console.log('the result is ', result);​

由于console.log只是调用process.stdout,另一种方法是使用如下包装魔术来捕获标准输出事件:

var util = require('util')

function hook_stdout(callback) {
    var old_write = process.stdout.write

    process.stdout.write = (function(write) {
        return function(string, encoding, fd) {
            write.apply(process.stdout, arguments)
            callback(string, encoding, fd)
        }
    })(process.stdout.write)

    return function() {
        process.stdout.write = old_write
    }
}

var unhook = hook_stdout(function(string, encoding, fd) {
    util.debug('stdout: ' + util.inspect(string))
    if( string == 'foobar' ) { unhook(); }
});
于 2012-10-09T18:55:10.873 回答
5

也许最好将当前控制台转发到新创建的上下文对象:

let contextObj = {
    console: console
};
于 2021-06-16T07:31:08.600 回答
2

我找到了另一个更简单的解决方案,恕我直言:我们只需要覆盖console.log()VM 上下文中的函数即可使用外部上下文中的函数。

import { Script, createContext } from 'vm';

let contextObj = {
    console: {
        log: (...args) => {
            console.log(...args);
        }
    }
};

const vmContext = createContext(contextObj);
const script = new Script("console.log('hello from the other side');");
script.runInContext(vmContext);

希望它可以帮助任何寻找愚蠢简单的解决方案的人!

于 2021-01-28T00:14:36.947 回答