gpt4 book ai didi

node.js - 将句柄向下传递到管道

转载 作者:搜寻专家 更新时间:2023-10-31 23:03:23 26 4
gpt4 key购买 nike

说我有

node foo.js | node bar.js

有没有办法将 foo 的标准输入句柄传递给 bar.js?

在极少数情况下,我想在管道中进行反向通信。

至少我知道我可以发送 node bar.js node foo.js 的 pid。鉴于该 pid,在 *nix 上,我应该能够使用以下方式写入 foo 的标准输入:

/proc/<pid>/fd/0

但是有没有办法在 MacOS 上做同样的事情?

最佳答案

所以有不同的方法。

方法 1 - IOCTL

这是灵感来自

https://stackoverflow.com/a/36522620/2830850

因此您创建了包含以下内容的writevt.c 文件

/*
* Mostly ripped off of console-tools' writevt.c
*/

#include <stdio.h>
#include <fcntl.h>
#include <termios.h>
#include <sys/ioctl.h>
#include <unistd.h>

char *progname;

static int usage() {
printf("Usage: %s ttydev text\n", progname);
return 2;
}

int main(int argc, char **argv) {
int fd, argi;
char *term = NULL;
char *text = NULL;

progname = argv[0];

argi = 1;

if (argi < argc)
term = argv[argi++];
else {
fprintf(stderr, "%s: no tty specified\n", progname);
return usage();
}

if (argi < argc)
text = argv[argi++];
else {
fprintf(stderr, "%s: no text specified\n", progname);
return usage();
}

if (argi != argc) {
fprintf(stderr, "%s: too many arguments\n", progname);
return usage();
}

fd = open(term, O_RDONLY);
if (fd < 0) {
perror(term);
fprintf(stderr, "%s: could not open tty\n", progname);
return 1;
}

while (*text) {
if (ioctl(fd, TIOCSTI, text)) {
perror("ioctl");
return 1;
}
text++;
}

return 0;
}

使用下面的代码编译它

gcc -o writevt writevt.c

然后给同一个添加root权限

sudo chown root:wheel writevt
sudo chmod 4755 writevt

现在我用下面的代码创建了一个简单的foo.js

var stdin = process.openStdin();

stdin.addListener("data", function(d) {
console.log(process.env.NAME + " entered: [" +
d.toString().trim() + "]");
});

然后在终端中首先运行 tty 命令

$ tty
/dev/ttys019

现在运行如下代码

NAME=A node foo.js  | NAME=B node foo.js

现在从另一个终端运行下面​​的命令

./writevt /dev/ttys019 "FROM external command^M"

^M 在 Mac 上是 CTRL+V + CTRL+ENTER

Content

正如您从 gif 中看到的,输入到达 A 的 stdin,然后 A 在标准输出上打印,然后由 B 接收。所以如果我像下面这样修改代码

var stdin = process.openStdin();

stdin.addListener("data", function(d) {
console.log(process.env.NAME + " entered: [" +
d.toString().trim() + "]");
});

if (process.env.NAME === "B") {
setInterval(function() {
require('child_process').exec(`./writevt /dev/ttys019 "Hello from B?
"`)
}, 1000)
}

注意 1:^M 是在上面的代码中使用 Vim 添加的

注意 2:TTY 位置已硬编码在此,但您可以通过运行

通过环境变量传递它
export TTY=`tty`

然后在代码中使用process.env.TTY。更新后的结果是

Working

方法 2 - FIFO 文件

在这种方法中,您首先制作一个 fifo 文件

$ mkfifo nodebridge

现在你改变你的代码如下

var stdin = process.openStdin();
var fs = require("fs")
stdin.addListener("data", function(d) {
console.log(process.env.NAME + " entered: [" +
d.toString().trim() + "]");
});

if (process.env.NAME === "B") {
setInterval( () => {
require('child_process').exec('printf "Hello from B?\\n" > nodebridge')
}, 1000);
}

然后运行如下命令

NAME=A node foo.js < nodebridge | NAME=B node foo.js

NodeBridge

关于node.js - 将句柄向下传递到管道,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47270986/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com