【问题标题】:python, how to run commands on remote hosts and show output in GUI in real time?python,如何在远程主机上运行命令并在 GUI 中实时显示输出?
【发布时间】:2015-12-07 15:45:19
【问题描述】:

我知道这是一个真正的开放式问题,但我是 python 新手,正在构建一个简单的一次性网络应用程序,为非技术团队提供一些自助服务功能。这个团队有一堆重复的任务,他们把这些任务交给了另一个团队,这些任务只是乞求自动化,比如在远程主机上重新启动一些进程、grep 日志、清理旧文件、部署/重新启动应用程序的新版本、获取最新版本运行版本等。用户将单击按钮并观看 GUI 中的输出,他们不会手动输入命令来运行(我知道这很危险)。任何新任务都将由技术支持团队编写脚本并添加到应用程序中。

现在,我唯一不确定的是如何将命令的(接近)实时输出返回到 GUI。我过去用 PHP 构建了一个非常相似的应用程序,我所做的是将远程命令的输出刷新到数据库,然后使用 ajax 轮询数据库并附加新的输出。即使输出会以块的形式返回,它也非常简单并且效果很好(我将输出逐行写入 GUI,所以它看起来像是实时的)。有一个更好的方法吗?我正在考虑使用 Web 套接字将命令的输出推回 GUI。好主意?馊主意? python库有什么更好的吗?我也可以使用 nodejs,如果这有什么不同的话,但是我对这两种语言都是新手(我已经启动并运行了一个简单的 python 烧瓶应用程序,它作为一个 API 将一些业务应用程序粘合在一起,没什么大不了的在节点中重写)。

【问题讨论】:

    标签: python node.js websocket


    【解决方案1】:

    这是一个宽泛的问题,但我会给你一些线索。

    很好的例子是LogIo。一旦您愿意运行一些命令而不是将输出推送到 GUI,使用 Node.js 就成为自然的方法。此应用可能包含一些元素:

    • 第一部分,运行命令并收集输出并将其推送到
    • 第二部分,接收输出并将其保存到数据库/文件。保存后,这部分正在向
    • 抛出事件
    • 第三部分,应该是一个 websocket 服务器,它将处理在线用户并将事件分发给
    • 第四部分, 这将是预先编写好的脚本 GUI,能够通过 websocket 连接到第三部分,登录用户,接收事件并将它们广播到其他 GUI 元素。

    一旦我假设你觉得 PHP 比 python 更强大,你最简单的方法是创建 第二部分 作为一个 PHP 服务来处理输入(将收获的输出保存到 db),比方说使用 UDP 包到第三部分的 UDP 监听套接字。

    第一部分将是 python 脚本,用于获取命令输出并将其正确绕过到第二部分。它应该像往常一样容易处理 grep 案例:

    tail -f /var/log/apache2/access.log | /usr/share/bin/myharvester 
    

    在开发它的某个时候,您将需要在 myharvester 之后将用户或单一任务 ID 作为参数传递给那里。

    创建一个 Node.js 脚本作为第三部分,这比您想象的要容易但棘手。作为一个单实例脚本,它应该能够接收输入并将其作为事件绕过给用户。我以前做过这样的事情:

    var config = {};
    var app = require('http').createServer().listen(config.server.port);
    
    var io = require('socket.io').listen(app);
    
    var listenerDgram = require('dgram').createSocket('udp4');
    listenerDgram.bind(config.listeners.udp.port);
    
    var sprintf = require('sprintf').sprintf;
    
    var users = [];
    
    app.on('error', function(er) {
        console.log(sprintf('[%s] [ERROR] HTTP Server at port %s has thrown %s', Date(), config.server.port, er.toString()));
        process.exit();
    });
    
    listenerDgram.on('error', function(er) {
        console.log(sprintf('[%s] [ERROR] UDP Listener at port %s has thrown %s', Date(), config.listeners.udp.port, er.toString()));
        process.exit();
    });
    
    listenerDgram.on('message', function(msg, rinfo) {
        // handling, let's say, JSONized msg from part two script,
        // buildinf a var frame and finally
        if(user) {
            // emit to single user based on what happened
            // inside this method
            users[user].emit('notification', frame);
        } else {
            // emit to all users
            io.emit('notification', frame);
        }
    
    });
    
    io.sockets.on('connection', function(socket) {
        // handling user connection here and pushing users' sockets to
        // users aray.
    });
    

    这个废料是没有用逻辑填充你需要的基本示例。脚本应该能够在给定端口上打开 UDP 侦听器,并在 websockets 中侦听运行到它的用户。老实说,一旦你在 Node.js 中变得很好,你可能想用它来修复 第二部分 + 第三部分,什么会让你失去 UDP 部分,因为收割机会将输出直接推送到脚本,这样可以维护里面的websocket。但它有一个缺点,就是从其他后端复制一些逻辑作为 CRM。

    最后(第四)部分是使用 JavaScript 实现 Web 界面,将当前登录的用户连接到套接字服务器。

    我以前使用过类似的方法,它是实时工作的,因此我们可以在电话真正开始响铃之前向我们的呼叫中心员工显示有关来电的信息。最后,解决方案(不包括 CRM 的接口)在两个脚本中关闭 - 专用 CRM API 部分(所有逻辑发生的地方)来处理来自 Asterisk 和 Node.js 事件转发器的事件。

    【讨论】:

    • 感谢您的详细回答。这太棒了。我一定会试一试的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-17
    • 1970-01-01
    • 2016-06-14
    • 1970-01-01
    相关资源
    最近更新 更多