无法创建/dev/stdout:没有这样的设备或地址 [英] cannot create /dev/stdout: No such device or address
问题描述
我想通过node运行shell命令并捕获stdout的结果.我的脚本可以在OSX上正常运行,但不能在Ubuntu上运行.
I'm want to run a shell command via node and capture the result of stdout. My script works fine on OSX, but not on Ubuntu.
我已将问题和脚本简化为以下节点脚本:
I've simplified the problem and script to the following node script:
var execSync = require('child_process').execSync,
result = execSync('echo "hello world" >> /dev/stdout');
// Do something with result
结果:
/bin/sh:1:无法创建/dev/stdout:没有此类设备或地址
/bin/sh: 1: cannot create /dev/stdout: No such device or address
- 我尝试用
/dev/fd/1
替换 - 我尝试将shell更改为bash ...
execSync('echo ...',{shell:'/bin/bash'})
/dev/stdout
就像我说的那样,上面的问题得到了简化.真实的脚本接受应在其中写入结果的文件的名称作为参数,因此我需要通过提供对stdout流作为文件描述符的访问来解决此问题,即/dev/stdout
.
Like I said, the problem above is simplified. The real script accepts as a parameter the name of a file where results should be written, so I need to resolve this by providing access to the stdout stream as a file descriptor, i.e. /dev/stdout
.
我如何通过节点执行命令,同时赋予命令对自己的 stdout流的访问权限?
How can I execute a command via node, while giving the command access to its own stdout stream?
推荐答案
在/dev/stdout
我无权访问OSX机器,而是从此问题访问在 phantomjs
上,似乎在OSX/BSD和Linux上,/dev/stdout
都是符号链接,但是它们之间的工作方式似乎有所不同.其中一位评论者说,在OSX上使用/dev/stdout
是标准的,但在Linux上则不使用.在另一个随机位置中,我读到这样的语句:暗示/dev/stdout
几乎是OSX的东西.在此答案中可能有一个线索关于为什么它在Linux上不起作用的提示(似乎隐式关闭文件描述符)当以这种方式使用时.)
On /dev/stdout
I don't have access to an OSX box, but from this issue on phantomjs
, it seems that while on both OSX/BSD and Linux /dev/stdout
is a symlink, nonetheless it seems to work differently between them. One of the commenters said it's standard on OSX to use /dev/stdout
but not for Linux. In another random place I read statements that imply /dev/stdout
is pretty much an OSX thing. There might be a clue in this answer as to why it doesn't work on Linux (seems to implicitly close the file descriptor when used this way).
其他相关问题:
我在Arch上尝试了您的代码,确实给了我同样的错误,就像上面提到的变体一样-因此这与Ubuntu无关.
I tried your code on Arch and it indeed gives me the same error, as do the variations mentioned - so this is not related to Ubuntu.
我找到了博客文章,其中介绍了如何将文件描述符传递给 execSync
.将其与我从此处所获得的内容一起此处,我编写了此代码的修改后的版本:
I found a blog post that describes how you can pass a file descriptor to execSync
. Putting that together with what I got from here and here, I wrote this modified version of your code:
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
中命令输出的位置.这样就可以使用文件描述符了.如果希望被调用的程序输出到由继承的 stdout
和 stderr
,则仍可以传递 1
和 2
它的父级,您已经在评论中提到了.
Unless I misunderstood your question, you want to be able to change where the output of the command in execSync
goes. With this you can, using a file descriptor. You can still pass 1
and 2
if you want the called program to output to stdout
and stderr
as inherited by its parent, which you've already mentioned in the comments.
供以后参考,该版本适用于内核版本为 4.10.9-1-ARCH
的Arch,版本为 bash 4.4.12
和 node v7.7.3
.
For future reference, this worked on Arch with kernel version 4.10.9-1-ARCH
, on bash 4.4.12
and node v7.7.3
.
这篇关于无法创建/dev/stdout:没有这样的设备或地址的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!