0

让我们以显示系统信息并定期更新它的“顶级”应用程序为例。

我想使用 node.js 运行它并显示该信息(和更新!)。我想出的代码:

#!/usr/bin/env node

var spawn = require('child_process').spawn;

var top = spawn('top', []);

top.stdout.on('readable', function () {
    console.log("readable");
    console.log('stdout: '+top.stdout.read());
});

它的行为不像我预期的那样。事实上它什么也没产生:

readable
stdout: null
readable
stdout:
readable
stdout: null

然后退出(这也是意料之外的)。

仅以top应用为例。目标是通过节点代理这些更新并将它们显示在屏幕上(与直接从命令行运行 top 的方式相同)。

我最初的目标是编写脚本以使用 scp 发送文件。这样做然后注意到我缺少 scp 本身显示的进度信息。环顾四周 scp 节点模块,他们也没有代理它。所以回溯到像top这样的常见应用程序。

4

1 回答 1

2

top是一个交互式控制台程序,旨在针对实时伪终端运行。

至于您的stdout阅读,top看到它stdin不是 tty 并退出并出现错误,因此在stdout. 你可以在 shell 中看到这种情况,如果你这样做echo | top它会退出,因为 stdin 不会是 tty。

即使它实际上正在运行,它的输出数据也将包含用于操作固定尺寸控制台的控制字符。(如“将光标移动到第 2 行的开头”)。它是一个交互式用户界面,不适合作为编程数据源。“屏幕抓取”和解释这些数据并提取有意义的信息将非常困难和脆弱。您是否考虑过一种更简洁的方法,例如从/proc/meminfo文件和内核为此目的公开的其他特殊文件中获取所需的数据?最终top是从现成的特殊文件和系统调用中获取所有这些数据,因此您应该能够利用便于编程访问的数据源,而不是试图筛选顶部。

当然,现在top有分析代码来做平均值等等,你可能必须重新实现,所以屏幕抓取和通过干净的数据源都有优点和缺点,并且容易和困难的方面。但我的 0.02 美元将专注于良好的数据源,而不是尝试筛选控制台 UI。

要考虑的其他选项/资源:

为了清楚起见,是的,当然可以top作为子进程运行,欺骗它认为有一个 tty 和所有相关的环境设置,并获取它正在写入的数据。这非常复杂,类似于试图通过在电视屏幕上拍摄天气频道的照片并在其上运行光学字符识别来获取天气。风格要点,但有更简单的方法。expect如果您需要研究更多关于诱使控制台程序作为子进程运行的信息,请查看该命令。

于 2013-07-03T20:06:04.533 回答