我想通过节点运行一个shell命令并捕获stdout的结果。 我的脚本在OSX上正常工作,但不在Ubuntu上。
我已经将问题和脚本简化为以下节点脚本:
var execSync = require('child_process').execSync, result = execSync('echo "hello world" >> /dev/stdout'); // Do something with result
结果是:
/ bin / sh:1:不能创build/ dev / stdout:没有这样的设备或地址
/dev/stdout
/dev/fd/1
replace/dev/stdout
execSync('echo ...', {shell : '/bin/bash'})
就像我说的,上面的问题被简化了。 真正的脚本接受作为参数的结果应写入文件的名称,所以我需要通过提供对stdoutstream作为文件描述符(即/dev/stdout
访问来解决此问题。
我怎样才能通过节点执行命令,同时给命令访问它自己的标准输出stream?
/dev/stdout
我没有访问OSX框,但是从phantomjs
上的这个问题看来,尽管在OSX / BSD和Linux /dev/stdout
都是符号链接,但是它们之间似乎有不同的工作方式。 其中一位评论者表示,在OSX上使用/dev/stdout
但不适用于Linux。 在另一个随机的地方,我读了一些暗示/dev/stdout
几乎是OSX的东西。 这个答案可能有一个线索,为什么它不能在Linux上工作(似乎用这种方式隐式关闭文件描述符)。
更多相关问题:
我在Arch上尝试了你的代码,它确实给了我同样的错误,就像提到的变体一样 – 所以这和Ubuntu没有关系。
我发现了一篇博文 ,描述了如何将文件描述符传递给execSync
。 把这些与我从这里和这里得到的一起放在一起,我写了这个代码的修改版本:
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
命令的输出所在的execSync
。 有了这个,你可以使用文件描述符。 如果您希望被调用的程序输出到stdout
和stderr
,您仍然可以传递1
和2
,这是由父级继承的,您已经在注释中提到了这一点。
为了将来的参考,这个工作Arch与内核版本4.10.9-1-ARCH
,在bash 4.4.12
和node v7.7.3
。