简体   繁体   English

从Node.js中的Shell脚本读取二进制输出

[英]Reading binary output from a shell script in Node.js

I need to execute a shell command from my Node.js script, read its output and terminate that program after a certain number of bytes is read. 我需要从Node.js脚本执行shell命令,读取其输出,并在读取一定数量的字节后终止该程序。 (More precisely, I want to do a partial download of a file via smbget ). (更确切地说,我想通过smbget进行文件的部分下载)。

The most obvious approach, I guess, is to use childprocess.spawn() , buffer the output manually and simply kill() the process when sufficient data was read. 我猜,最明显的方法是使用childprocess.spawn() ,手动缓冲输出,并在读取足够的数据时简单地kill()进程。

And this works nicely, except that I looks a bit clunky. 而且效果很好,除了我看上去笨拙。 So instead I wanted to be clever (TM) and use head . 因此,我想变得聪明(TM)并使用head So I wired everything up as indicated in the docs to child_process (or, somewhat more conveniently, using procstreams ) to produce a pipeline equivalent to cat /dev/urandom | head --bytes=10 因此,我按照文档中的指示将所有内容连接到child_process (或者更方便地使用procstreams ),以产生与cat /dev/urandom | head --bytes=10等效的管道cat /dev/urandom | head --bytes=10 cat /dev/urandom | head --bytes=10 . cat /dev/urandom | head --bytes=10 Alas, everything goes up in flames like so: everything,一切如火如荼地上升:

events.js:72
     throw er; // Unhandled 'error' event
             ^

Error: read ECONNRESET
    at errnoException (net.js:883:11)
    at Pipe.onread (net.js:539:19)

probably because head just clubs the stream to death, and I couldn't find a way to catch or otherwise handle that error (although that could just be because I'm a node n00b :). 可能是因为head只是将信息流压死了,并且我找不到捕捉或以其他方式处理该错误的方法(尽管那可能只是因为我是节点n00b :)。

Alternatively, I could do the following: 另外,我可以执行以下操作:

var cmd = 'cat /dev/urandom | head --bytes=100';
childprocess.exec(cmd, function (err, stdout, stderr) {
    // ...
});

except that I can't access the raw (binary) data anymore. 除了我无法再访问原始(二进制)数据。 When I call 当我打电话

fs.writeFileSync('foo.dat', stdout);

the stream will be utf8 encoded, resulting in the file being around 180 bytes instead of the expected 100 bytes. 该流将被utf8编码,从而导致文件约为180个字节,而不是预期的100个字节。

This can be circumvented by passing a second parameter to exec : 这可以通过将第二个参数传递给exec来避免:

{ encoding: 'binary' }

Unfortunately, the docs say that this is deprecated. 不幸的是,文档说这已被弃用。

What is the correct way of doing this? 正确的做法是什么? Or do I absolutely need to buffer myself? 还是我绝对需要缓冲一下自己?

Technically you should be able to pass 'buffer' as an encoding and have it output a Buffer specifically, but looks like that's not the case. 从技术上讲,您应该能够将“缓冲区”作为一种编码传递,并使其专门输出一个缓冲区,但事实并非如此。 I've opened a ticket for it and that should be fixed before v0.12 release. 我已经为它打开了一张票 ,应该在v0.12发布之前解决。

For the time being feel free to use binary encoding. 暂时可以使用二进制编码。 It was only sort of deprecated, but will never go away. 它只是被弃用,但永远不会消失。 In v0.11 it received some love and is now synonymous with latin1 encoding. 在v0.11中, 它获得了一些喜爱 ,现在与latin1编码同义。 Which is officially supported by v8, so support won't be going away any time soon. v8正式支持该功能,因此支持不会很快消失。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM