让我们以"top“应用程序为例,它显示系统信息并定期更新。
我想使用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这样的常见应用程序。
发布于 2013-07-03 20:06:05
top
是一个交互式控制台程序,设计用于在实时伪终端上运行。
至于您的stdout
读取,top
发现它的stdin
不是tty,并以错误退出,因此在stdout
上没有输出。您可以在shell中看到这种情况,如果您执行echo | top
,它将退出,因为标准输入将不是tty。
即使它实际正在运行,它的输出数据也将包含用于操作固定维度控制台的控制字符。(如“将光标移动到第2行的开头”)。它是一个交互式用户界面,作为编程数据源是一个糟糕的选择。“屏幕抓取”和解释这些数据并提取有意义的信息将是相当困难和脆弱的。您是否考虑过一种更干净的方法,比如从/proc/meminfo
文件和内核为此公开的其他特殊文件中获取所需的数据?最终,top
将从现成的特殊文件和系统调用中获取所有这些数据,因此您应该能够利用便于编程访问的数据源,而不是试图筛选顶部。
当然,现在top
有分析代码来做平均值等等,你可能必须重新实现,所以屏幕抓取和查看干净的数据源都有优缺点,也有容易和困难的方面。但我的0.02美元将专注于良好的数据源,而不是试图屏幕抓取控制台UI。
要考虑的其他选项/资源:
诸如free -m
vmstat
的控制台程序
为了清楚起见,确实可以将top
作为子进程运行,欺骗它认为有tty和所有相关的环境设置,并获取它正在写入的数据。它非常复杂,类似于试图通过在电视屏幕上拍摄天气频道的照片并在其上运行光学字符识别来获取天气。风格,但还有更简单的方法。如果您需要研究更多关于诱使控制台程序作为子进程运行的信息,请查看expect
命令。
https://stackoverflow.com/questions/17456820
复制相似问题