无法创建/ dev / stdout:没有这样的设备或地址

时间:2016-10-28 09:15:15

标签: node.js linux bash sh

我想通过节点运行shell命令并捕获stdout的结果。我的脚本在OSX上运行正常,但在Ubuntu上运行不正常。

我已将问题和脚本简化为以下节点脚本:

var execSync = require('child_process').execSync,
    result = execSync('echo "hello world" >> /dev/stdout');

// Do something with result

结果:

  

/ bin / sh:1:无法创建/ dev / stdout:没有这样的设备或地址

  • 我尝试用/dev/stdout
  • 替换/dev/fd/1
  • 我尝试将shell更改为bash ... execSync('echo ...', {shell : '/bin/bash'})

就像我说的,上面的问题被简化了。真实脚本接受应该写入结果的文件名作为参数,因此我需要通过提供对作为文件描述符的stdout流的访问来解决这个问题,即/dev/stdout

如何通过节点执行命令,同时让命令可以访问自己的标准输出流?

1 个答案:

答案 0 :(得分:1)

/dev/stdout

我无法访问OSX框,但是phantomjs上的this issue,似乎在OSX / BSD和Linux /dev/stdout上都是符号链接,但它仍然是似乎他们之间的工作方式不同。其中一位评论者表示OSX的标准是使用/dev/stdout而不是Linux。在another random place中我读到了暗示/dev/stdout几乎是OSX的陈述。可能有一条线索in this answer,说明为什么它在Linux上不起作用(似乎以这种方式隐式关闭文件描述符)。

其他相关问题:

解决方案

我在Arch上尝试了你的代码,它确实给了我同样的错误,就像上面提到的变化一样 - 所以这与Ubuntu无关。

我找到了一个blog post,它描述了如何将文件描述符传递给execSync。把它与我从herehere得到的结果放在一起,我写了你的代码的修改版本:

var fs = require('fs');
var path = require('path');

var fdout = fs.openSync(path.join(process.cwd(), 'stdout.txt'), 'a');
var fderr = fs.openSync(path.join(process.cwd(), 'stderr.txt'), 'a');

var execSync = require('child_process').execSync,
    result = execSync('echo "hello world"', {stdio: [0,fdout,fderr] });

除非我误解了您的问题,否则您希望能够更改execSync中命令输出的位置。有了这个,您可以使用文件描述符。如果您希望被调用程序输出到其父级继承的12,您仍然可以传递stdoutstderr,您已在评论中提及

为了便于将来参考,我在4.10.9-1-ARCHbash 4.4.12上使用内核版node v7.7.3的Arch工作。