最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Flask運用Xterm實現(xiàn)交互終端的示例詳解

 更新時間:2023年11月28日 09:21:22   作者:微軟技術(shù)分享  
Xterm是一個基于X Window System的終端仿真器(Terminal Emulator),Xterm最初由MIT開發(fā),它允許用戶在X Window環(huán)境下運行文本終端程序,本文給大家介紹了Flask運用Xterm實現(xiàn)交互終端的示例詳解,文中有詳細的代碼講解,需要的朋友可以參考下

前言

Xterm是一個基于X Window System的終端仿真器(Terminal Emulator)。Xterm最初由MIT開發(fā),它允許用戶在X Window環(huán)境下運行文本終端程序。Xterm提供了一個圖形界面終端,使用戶能夠在圖形桌面環(huán)境中運行命令行程序。而xterm.js是一個用于在瀏覽器中實現(xiàn)終端仿真的JavaScript庫。它允許在Web頁面中創(chuàng)建交互式的終端界面,用戶可以在瀏覽器中運行命令行程序,執(zhí)行命令,并與終端進行交互。

主要特點和功能包括:

  1. 終端仿真: xterm.js通過JavaScript模擬了一個終端環(huán)境,支持常見的終端功能,包括光標移動、顏色控制、滾動等。
  2. 多平臺支持: 由于是基于JavaScript實現(xiàn),xterm.js可以在各種現(xiàn)代瀏覽器上運行,無論是在桌面還是移動設(shè)備上。
  3. 自定義外觀: xterm.js提供了豐富的配置選項,用戶可以定制終端的外觀和行為,包括顏色、字體、光標樣式等。
  4. 剪貼板支持: 支持從終端復(fù)制文本到剪貼板,并從剪貼板粘貼文本到終端。
  5. WebSockets和其他集成: 可以與WebSockets等通信協(xié)議集成,以便在瀏覽器中實現(xiàn)實時的終端交互。
  6. 支持Unicode和UTF-8: 能夠正確顯示和處理Unicode字符,支持UTF-8編碼。

xterm.js通常被用于Web應(yīng)用程序中,尤其是在需要提供命令行界面的場景下,如在線終端、遠程服務(wù)器管理等。這使得開發(fā)者能夠在瀏覽器中實現(xiàn)類似于本地終端的交互體驗,而無需使用本地終端模擬器。

AJAX 實現(xiàn)Web交互

AJAX(Asynchronous JavaScript and XML)是一種用于在Web應(yīng)用程序中實現(xiàn)異步數(shù)據(jù)交換的技術(shù)。它允許在不重新加載整個頁面的情況下,通過在后臺與服務(wù)器進行小規(guī)模的數(shù)據(jù)交換,實現(xiàn)動態(tài)更新網(wǎng)頁內(nèi)容的目的。AJAX廣泛用于創(chuàng)建交互性強、用戶體驗良好的Web應(yīng)用程序,例如在加載新數(shù)據(jù)、進行表單驗證、實現(xiàn)自動完成搜索等方面。

如下前端部分,通過使用ajax向后端提交數(shù)據(jù),當success:function接收到數(shù)據(jù)后直接將數(shù)據(jù)動態(tài)回寫到Xterm終端上,代碼如下所示;

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <link rel="stylesheet"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  />
    <script type="text/javascript" src="https://www.lyshark.com/javascript/xterm/xterm.js"></script>
    <script type="text/javascript" src="https://www.lyshark.com/javascript/jquery/3.5.1/jquery.min.js"></script>
</head>
<body>
    <script type="text/javascript">
      var window_width = $(window).width()-200;
      var window_height = $(window).height()-300;
      var term = new Terminal(
            {
                cols: Math.floor(window_width/9),
                rows: Math.floor(window_height/20),
                useStyle:false,
                convertEol: true,
                cursorBlink:false,
                cursorStyle:null,
                rendererType: "canvas",
            }
    );
    term.open(document.getElementById('terminal'));
      function show(){
          var address = $("#address").val();
          var command = $("#command").val();
          console.log(command);
          $.ajax({
              url:"/",
              type:"POST",
              contentType:"application/json;",
              data: JSON.stringify({"address":address,"command":command}),
              success:function (res)
              {
                  // term.clear();
                  term.writeln( "\x1B[1;3;33m IP地址: \x1B[0m" + res.address );
                  term.writeln( "\x1B[1;3;34m 命令: \x1B[0m" + res.command );
              }
          });
      }
    </script>

    <!--提交數(shù)據(jù)-->
    <div id="terminal"></div>
        <input type="text" id="address" placeholder="主機地址"/>
        <input type="text" id="command" placeholder="執(zhí)行命令"/>
        <input type="button" value="執(zhí)行命令" onclick="show()">
    </div>
</body>
</html>

后端部分的實現(xiàn)很簡單,首先封裝一個ssh_shell用于執(zhí)行命令,用戶傳入數(shù)據(jù)后,直接執(zhí)行并將返回結(jié)果放入到ref內(nèi)即可。

from flask import Flask,render_template,request
from flask import jsonify
import paramiko

app = Flask(__name__)

ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())

def ssh_shell(address,username,password,port,command):
    ssh.connect(address,port=port,username=username,password=password)
    stdin, stdout, stderr = ssh.exec_command(command)
    result = stdout.read()
    if not result:
        result=stderr.read()
    ssh.close()
    return result.decode()

@app.route('/', methods=[ 'GET', 'POST'])
def index():
    if request.method == "POST":
        # 接收數(shù)據(jù)
        json_value = request.get_json()
        ref = ssh_shell("192.168.150.128","root","123123","22",json_value["command"])

        # 發(fā)送數(shù)據(jù)
        info = dict()
        info["address"] = json_value["address"]
        info["command"] = ref
        return jsonify(info)
    else:
        return render_template("index.html")

if __name__ == '__main__':
    app.run()

AJAX實現(xiàn)Web終端

繼續(xù)擴展將編輯框去掉,用戶輸入數(shù)據(jù)后直接傳入到Xterm內(nèi),Xterm里賣弄判斷如果出現(xiàn)了回車,則像后端發(fā)送ajax數(shù)據(jù),否則繼續(xù)偵聽并記下輸入數(shù)據(jù)。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <link rel="stylesheet"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  />
    <script type="text/javascript" src="https://www.lyshark.com/javascript/xterm/xterm.js"></script>
    <script type="text/javascript" src="https://www.lyshark.com/javascript/jquery/3.5.1/jquery.min.js"></script>
</head>
<body>
    <div id="terminal"></div>

    <script type="text/javascript">
        var window_width = $(window).width()-500;
        var window_height = $(window).height()-300;
        var term = new Terminal
        (
            {
                cols: Math.floor(window_width/9),
                rows: Math.floor(window_height/20),
                useStyle:false,
                convertEol: true,
                cursorBlink: true,        //光標閃爍
                cursorStyle: "underline", //光標樣式
                rendererType: "canvas",
            }
        );
        term.open(document.getElementById('terminal'));
        term.writeln("welcome to lyshark web terminal!");
        term.write("[shell] # ");

        let input = '';
        term.on('key', (key, ev) => {
          let code = key.charCodeAt(0);
          console.log(code);

          // 如果按下回車,則發(fā)送命令,并等待輸出結(jié)果
          if(code == 13)
          {
              term.write("\r\n");
              $.ajax({
                  url:"/",
                  type:"POST",
                  contentType:"application/json;",
                  data: JSON.stringify({"command": input}),
                  success:function (res)
                  {
                      term.write(res.value);
                  }
              });
              input ='';
          }
          // 如果是退格,則清除
          else if(code == 127)
          {
              term.write("\b");
          }
          else
          {
              input += key
              term.write(key);
          }
        });
    </script>
</body>
</html>

后端收到數(shù)據(jù)后解析命令,比對命令是否存在,根據(jù)不同的命令執(zhí)行不同的分支。

from flask import Flask,render_template,request
from flask import jsonify

app = Flask(__name__)

@app.route('/', methods=[ 'GET', 'POST'])
def index():
    if request.method == "POST":
        # 接收數(shù)據(jù)
        json_value = request.get_json()["command"]
        if len(json_value) != 0:

            # 判斷使用哪一個分支
            splite_value = json_value.split(" ")
            info = dict()

            if splite_value[0] == "help":
                info["value"] = "version 1.0"
                info["value"] = info["value"] + "\n[shell] # "
                return jsonify(info)

            elif splite_value[0] == "GetCPU":
                address = splite_value[1]
                info["value"] = "192.168.1 CPU 10%"
                info["value"] = info["value"] + "\n[shell] # "
                return jsonify(info)
            else:
                info["value"] = "命令不存在"
                info["value"] = info["value"] + "\n[shell] # "
                return jsonify(info)
        else:
            info = dict()
            info["value"] = "[shell] # "
            return jsonify(info)
    else:
        return render_template("index.html")

if __name__ == '__main__':
    app.run()

運行后可輸出一個交互式WebShell環(huán)境,如下圖所示;

WebSocket 實現(xiàn)終端

雖然WebSSH可以方便管理主機,但如果需要批量運維則需要開發(fā)一個可以多條消息共同推送的命令行。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <link rel="stylesheet"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  />
    <script type="text/javascript" src="https://www.lyshark.com/javascript/xterm/xterm.js"></script>
    <script type="text/javascript" src="https://www.lyshark.com/javascript/jquery/3.5.1/jquery.min.js"></script>
    <script type="text/javascript" src="https://www.lyshark.com/javascript/socket.io/socket.io.min.js"></script>
</head>

<body>
    <div id="terminal"></div>

    <script type="text/javascript" charset="UTF-8">
        $(document).ready(function()
        {
            namespace = '/Socket';
            var socket = io.connect("http://" + document.domain + ":" + location.port + namespace);

            var window_width = $(window).width()-500;
            var window_height = $(window).height()-300;
            var term = new Terminal
            (
                {
                    cols: Math.floor(window_width/9),
                    rows: Math.floor(window_height/20),
                    useStyle:false,
                    convertEol: true,
                    cursorBlink: true,
                    rendererType: "canvas",
                }
            );

            // 打開Web終端
            term.open(document.getElementById('terminal'));
            term.write("[shell] # ");

            let input_command = '';

            term.on('key', (key, ev) => {
              let code = key.charCodeAt(0);
              console.log(code);

              // 如果按下回車,則發(fā)送命令,并等待輸出結(jié)果
              if(code == 13)
              {
                  // 發(fā)送數(shù)據(jù)到后端
                  term.write("\r\n");
                  socket.emit("message",{"command": input_command});
                  input_command ='';
              }
              // 如果是退格,則清除
              else if(code == 127)
              {
                  term.write("\b");
              }
              else
              {
                  input_command += key
                  term.write(key);
              }
            });

            // 接受后臺返回并輸出
            socket.on('response', function(recv)
            {
                console.log(recv.value);
                term.write(recv.value);
            });
        });
    </script>
</body>
</html>

后臺接收參數(shù),并更具不同的參數(shù)執(zhí)行不同的運維函數(shù),此處只做演示,具體功能需要自行編寫。

from flask import Flask,render_template,request
from flask_socketio import SocketIO

async_mode = None
app = Flask(__name__)
app.config['SECRET_KEY'] = "lyshark"
socketio = SocketIO(app)

@app.route("/")
def index():
    return render_template("index.html")

# 出現(xiàn)消息后,率先執(zhí)行此處
@socketio.on("message",namespace="/Socket")
def socket(message):
    print("接收到消息:",message['command'])

    command = message['command']

    if len(command) != 0:
        splite_command = command.split(" ")

        if splite_command[0] == "help":
            socketio.emit("response", {"value": "version 1.0 \n"}, namespace="/Socket")

        elif splite_command[0] == "Ping":
            if len(splite_command) == 2:
                index = splite_command[1]
                for each in range(int(index)):
                    socketio.sleep(0.1)
                    socketio.emit("response",{"value": str(each) + "\n"}, namespace="/Socket")
                socketio.emit("response", {"value": "\n[shell] # "}, namespace="/Socket")
        else:
            socketio.emit("response", {"value": "lyShell: command not found \n"}, namespace="/Socket")
    else:
        socketio.emit("response", {"value": "[shell] # "}, namespace="/Socket")

# 當websocket連接成功時,自動觸發(fā)connect默認方法
@socketio.on("connect",namespace="/Socket")
def connect():
    print("鏈接建立成功..")

# 當websocket連接失敗時,自動觸發(fā)disconnect默認方法
@socketio.on("disconnect",namespace="/Socket")
def disconnect():
    print("鏈接建立失敗..")

if __name__ == '__main__':
    socketio.run(app,debug=True)

Socket版本的將會更流暢,如下圖所示;

以上就是Flask運用Xterm實現(xiàn)交互終端的示例詳解的詳細內(nèi)容,更多關(guān)于Flask Xterm交互終端的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • 關(guān)于python爬蟲模塊urllib庫詳解

    關(guān)于python爬蟲模塊urllib庫詳解

    這篇文章主要介紹了關(guān)于python爬蟲模塊urllib庫詳解,學(xué)習(xí)爬蟲,最初的操作便是模擬瀏覽器向服務(wù)端發(fā)出請求,這里我們就學(xué)習(xí)使用urlib庫的用法,需要的朋友可以參考下
    2023-07-07
  • 解決Tensorflow sess.run導(dǎo)致的內(nèi)存溢出問題

    解決Tensorflow sess.run導(dǎo)致的內(nèi)存溢出問題

    今天小編就為大家分享一篇解決Tensorflow sess.run導(dǎo)致的內(nèi)存溢出問題,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-02-02
  • Python教程通過公共鍵對不同字典進行排序示例詳解

    Python教程通過公共鍵對不同字典進行排序示例詳解

    本篇文章是Python教程基礎(chǔ)篇,通過一些示例為大家講解Python通過公共鍵對不同字典進行排序的方式,有需要的朋友可以借鑒參考下,希望能夠有所幫助
    2021-09-09
  • 使用Python監(jiān)視指定目錄下文件變更的方法

    使用Python監(jiān)視指定目錄下文件變更的方法

    今天小編就為大家分享一篇使用Python監(jiān)視指定目錄下文件變更的方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-10-10
  • python隱藏類中屬性的3種實現(xiàn)方法

    python隱藏類中屬性的3種實現(xiàn)方法

    今天小編就為大家分享一篇python隱藏類中屬性的3種實現(xiàn)方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2019-12-12
  • Python?迭代器和生成器概念及場景分析

    Python?迭代器和生成器概念及場景分析

    yield 是 Python 中實現(xiàn)惰性計算和協(xié)程的核心工具,結(jié)合 send()、throw()、close() 等方法,能夠構(gòu)建高效、靈活的數(shù)據(jù)流和控制流模型,這篇文章主要介紹了Python?迭代器和生成器概念,需要的朋友可以參考下
    2025-04-04
  • Pytest中使用SQLAlchemy進行異步數(shù)據(jù)庫測試過程

    Pytest中使用SQLAlchemy進行異步數(shù)據(jù)庫測試過程

    本文詳細介紹了在pytest環(huán)境下使用SQLAlchemy的異步功能來管理數(shù)據(jù)庫連接和狀態(tài),通過不同的scope參數(shù)控制fixture的生命周期,確保測試的隔離性和可靠性,主要介紹了兩種測試隔離策略:每次重建和事務(wù)回滾
    2025-12-12
  • opencv?python模糊影像檢測效果

    opencv?python模糊影像檢測效果

    這篇文章主要介紹了opencv?python模糊影像檢測,本文只使用cv2和shutil庫,若想直接使用該腳本需安裝這兩個庫,通過實例代碼給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-03-03
  • 每個 Python 開發(fā)者都應(yīng)該知道的7種好用工具(效率翻倍)

    每個 Python 開發(fā)者都應(yīng)該知道的7種好用工具(效率翻倍)

    Python 從一種小的開源語言開始,到現(xiàn)在,它已經(jīng)成為開發(fā)者很受歡迎的編程語言之一。這篇文章主要介紹了每個 Python 開發(fā)者都應(yīng)該知道的7種好用工具(效率翻倍),需要的朋友可以參考下
    2021-03-03
  • Python技法之如何用re模塊實現(xiàn)簡易tokenizer

    Python技法之如何用re模塊實現(xiàn)簡易tokenizer

    當我們在Python中開始新的東西時,我通常首先看一些模塊或庫來使用,下面這篇文章主要給大家介紹了關(guān)于Python技法之如何用re模塊實現(xiàn)簡易tokenizer的相關(guān)資料,需要的朋友可以參考下
    2022-05-05

最新評論

磴口县| 晋中市| 双柏县| 汝南县| 新津县| 塔城市| 社会| 大余县| 理塘县| 安岳县| 寻甸| 延边| 南华县| 秭归县| 青田县| 张家界市| 淳化县| 望谟县| 竹山县| 遵化市| 景泰县| 四子王旗| 哈密市| 庆元县| 江川县| 宿州市| 教育| 基隆市| 昌黎县| 新干县| 罗平县| 盐亭县| 买车| 樟树市| 绍兴县| 安阳县| 名山县| 宝丰县| 永州市| 乌兰县| 舞钢市|