【问题标题】:Capturing secondary / tertiary stream to terminal / TTY将二级/三级流捕获到终端/TTY
【发布时间】:2016-11-14 21:25:05
【问题描述】:

见下图。我从启动进程 A 的终端运行命令,该命令启动服务器(进程 B),然后服务器将启动工作程序(进程 C)。我想将服务器的 stdout/stderr 流式传输到某个日志文件,但我希望工作人员的 stdout 和 stderr 流回终端。这里的所有进程都是 Node.js 进程。

不知道如何执行此操作或是否可能。我对它如何工作的唯一猜测是终端会话是否有某种句柄或 ID,我可以使用它并告诉工作进程流式传输到该句柄或 ID。我对 *nix 的了解还不够,不知道它是如何工作的。任何解释都会有所帮助。

这是一个视觉效果:

【问题讨论】:

  • LOL 抱歉,“视觉”在我的厨房柜台上出现了几天,在图片的左侧,上面写着“将 stdout/stderr 流回终端”

标签: node.js unix terminal tty


【解决方案1】:

使用 Node.js(因为 OP 中的所有进程都是 Node.js 进程),这是我发现的一种解决方案。

步骤1,在进程A中,获取当前的tty身份 终端/tty

const tty = String(cp.execSync('tty', {stdio:['inherit','pipe','pipe']})).trim();

第 2 步,将 tty 值从进程 A 传递给进程 B => 我通过了 使用 socket.io 的子进程的动态值(字符串)(您 也可以使用IPC)

this.emit('tty-value', tty);

第 3 步 在子进程 B 中,我使用fd = fs.openSync(tty) 来获取 正确的文件描述符。

const fd = fs.openSync(tty)

第 4 步然后我可以使用以下内容写入我要写入的终端

const strm = fs.createWriteStream(null, {fd: fd});

因此,当进程 B 创建子进程 C 时,它可以进行必要的调用,将 stdout/stderr 从进程 C 传递到上述流。

...这花了我一整天的时间才弄明白,所以把这个留在这里给任何人看

【讨论】:

  • 很好的答案。不得不做fs.openSync(tty, 'w+'),因为 api 已经改变了
【解决方案2】:

搞清楚 tty 的事情做得很好。不确定是否有更简单的方法可以做到这一点,但我有一些想法涉及在某种程度上欺骗你的问题,但从长远来看可能会更好。

  1. 使用像winstonbunyan 这样的日志框架。或者像timequerylog 这样的结构化日志系统。日志框架将允许多个记录器,一个可以转到一个文件,另一个可以转到标准输出。

  2. 使用 Cluster 内置的 Node 模块来创建 worker,并让 worker 将带有事件/数据的消息发送到 master。然后 master 可以记录这些标准输出。

【讨论】:

  • 是的,这取决于用例...我的用例不同,因为我正在编写一个库并且需要为该库的用户提供一定的用户友好体验,我希望他们成为能够在他们发出命令的同一终端中看到工作人员的标准输出,仅为方便起见
  • 换句话说,我已经将工作人员的标准输出发送到一个单独的日志文件,用户可以使用 tail -F 对其进行跟踪。但最重要的是,我还想将工作人员的标准输出发送回终端,这就是挑战。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-11-04
  • 1970-01-01
  • 1970-01-01
  • 2020-03-23
  • 1970-01-01
  • 2021-06-30
相关资源
最近更新 更多