php模仿终端的简单操作

效果图:
Laravel

blade模版:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Terminal Interaction</title>
    <style>
        body {
            font-family: 'Courier New', Courier, monospace;
            background-color: #1E1E1E; /* Darker Grey */
            color: #CCCCCC; /* Light Grey */
            padding: 20px;
        }
        .container {
            display: flex;
            align-items: flex-start;
        }
        .terminal {
            border: 2px solid #555;
            border-radius: 5px;
            padding: 10px;
            background-color: #111; /* Dark Grey */
            width: 52%;
            height: 300px;
            overflow: auto;
            margin-right: 20px;
        }
        .terminal p {
            margin: 0;
            padding: 0;
            transition: background-color 0.3s ease; /* 添加过渡效果 */
        }
        .terminal p:hover {
            background-color: #4CAF50; /* 鼠标悬停时的高亮颜色 - 绿色 */
            color: white; /* 文本颜色 - 白色 */
            cursor: pointer; /* 设置鼠标样式为手型 */
        }
        .memo {
            border: 2px solid #555;
            border-radius: 5px;
            padding: 10px;
            background-color: #111; /* Dark Grey */
            width: 48%;
            height: 300px;
            overflow: auto;
        }
        .memo p {
            margin: 0;
            padding: 0;
            transition: background-color 0.3s ease; /* 添加过渡效果 */
        }
        .memo p:hover {
            background-color: #4CAF50; /* 鼠标悬停时的高亮颜色 - 绿色 */
            color: white; /* 文本颜色 - 白色 */
            cursor: pointer; /* 设置鼠标样式为手型 */
        }
        input[type="text"], input[type="password"], textarea {
            height: 30px;
            border: 1px solid #555; /* Dark Grey */
            border-radius: 3px;
            padding: 5px;
            margin-right: 10px;
            background-color: #333; /* Grey */
            color: #CCCCCC; /* Light Grey */
            font-family: 'Courier New', Courier, monospace;
            flex: 1; /* 设置所有文本框的宽度比例相等 */
        }
        input[type="text"]:focus, input[type="password"]:focus, textarea:focus {
            outline: none;
            border-color: #4CAF50; /* Green */
        }
        input[type="text"]::placeholder, input[type="password"]::placeholder, textarea::placeholder {
            color: #888; /* Grey */
        }
        button {
            background-color: #4CAF50; /* Green */
            color: white;
            border: none;
            border-radius: 3px;
            padding: 10px 20px;
            cursor: pointer;
            font-size: 16px;
        }
        button:hover {
            background-color: #45a049; /* Darker Green */
        }
    </style>
</head>
<body>
<div class="container">
    <div class="terminal" id="terminal">
        <p>$ Welcome to Terminal by ZhouJiawei for AutoTest;</p>
    </div>
    <div class="memo" id="memo">
        <p>备忘录[点击可直接复制]</p>

        <br>
        <p>1.检查算法授权</p>
        <p>cd /home/nle/app/aibox/lic/bin && ./licCheck</p>
        <p>2.算法授权</p>
        <p>cd /home/nle/app/aibox/lic/bin && ./licGetFormCloud -u zjw_test -p GB#16@*0</p>
        <p>3.格式化磁盘</p>
        <p>mkfs.ext4 /dev/sda</p>
        <p>4.格式化TF</p>
        <p>mkfs.ext4 /dev/mmcblk0p1</p>
        <p>5.查看hosts文件</p>
        <p>cat /etc/hosts</p>
        <p>6.查看指定进程 如ffmpeg</p>
        <p>ps -ef | grep ffmpeg</p>
        <p>7.查看内存资源</p>
        <p>free</p>
        <p>8.上网认证</p>
        <p>curl -X POST "https://int.newland.com.cn/pts/portalLogin/loginPw?password=自己修改密码&loginid=zhoujiaw" -H "accept: application/json;charset=UTF-8"</p>




    </div>
</div>
<br>
<input type="text" id="serverIP" placeholder="服务器IP" value="192.168.2.203" oninput="clearTerminal()">
<input type="text" id="serverPort" placeholder="服务器端口" value="22124" oninput="clearTerminal()">
<input type="text" id="loginUsername" placeholder="登录用户名" value="root" oninput="clearTerminal()">
<input type="password" id="loginPassword" placeholder="密码 留空使用默认id_rsa密钥" oninput="clearTerminal()">
<br>
<textarea id="input" style="width: calc(70% - 300px); height: 100px; margin-top: 10px;" placeholder="请输入您的简单命令,多条命令用&&拼接,无法执行需要交互的命令" onkeydown="handleKeyPress(event)"></textarea>
<script>
    var terminal = document.getElementById('terminal');
    var serverIPInput = document.getElementById('serverIP');
    var serverPortInput = document.getElementById('serverPort');
    var loginUsernameInput = document.getElementById('loginUsername');
    var loginPasswordInput = document.getElementById('loginPassword');
    var input = document.getElementById('input');

    function clearTerminal() {
        terminal.innerHTML = ''; // 清空终端内容
        writeToTerminal('$ Welcome to Terminal by ZhouJiawei for AutoTest;');
    }

    // 处理用户输入
    function handleKeyPress(event) {
        if (event.keyCode === 13) { // 如果按下回车键
            event.preventDefault();
            sendCommand(); // 发送命令
        }
    }

    // 处理用户输入
    function sendCommand() {
        var command = input.value.trim(); // 获取用户输入的命令并去除首尾空格
        writeToTerminal('$root ' + command); // 将用户输入的命令显示在终端中
        // 发送命令和参数到 API
        fetch('/api/general/terminal', {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json'
            },
            body: JSON.stringify({
                command: command,
                ip: serverIPInput.value.trim(),
                port: serverPortInput.value.trim(),
                user: loginUsernameInput.value.trim(),
                password: loginPasswordInput.value.trim()
            })
        })
            .then(response => response.json())
            .then(data => {
                writeToTerminal(data.message); // 将API返回的消息显示在终端中
            })
            .catch(error => {
                writeToTerminal('Error: ' + error.message); // 处理错误
            });

        input.value = ''; // 清空输入框
    }


    function writeToTerminal(message) {
        var lines = message.split('\n'); // 将消息按换行符分割成多行
        lines.forEach(function(line) {
            terminal.innerHTML += '<p>' + line + '</p>'; // 为每行消息添加 <p> 标签
        });
        terminal.scrollTop = terminal.scrollHeight;
    }

    // 复制备忘录内容
    document.getElementById('memo').addEventListener('click', function(event) {
        var target = event.target; // 获取点击的元素
        if (target.tagName === 'P') { // 如果点击的是<p>标签
            var text = target.innerText; // 获取<p>标签内的文本内容

            // 创建一个文本域元素
            var textArea = document.createElement("textarea");
            // 设置文本域的值为要复制的文本内容
            textArea.value = text;
            // 将文本域添加到DOM中
            document.body.appendChild(textArea);
            // 选中文本域中的内容
            textArea.select();
            // 执行复制命令
            document.execCommand('copy');
            // 从DOM中移除文本域元素
            document.body.removeChild(textArea);
        }
    });
</script>

</body>
</html>
public function terminal(Request $request)
    {
        $command=$request->input('command');
        $ip=$request->input('ip');
        $port=$request->input('port');
        $user=$request->input('user');
        $password=$request->input('password');
        if($password){
            $rsa = $password;
        }else{
            $key = Storage::get('id_rsa');
            $rsa = PublicKeyLoader::load($key);
        }
        //连接的服务器ip 输入方式 密钥登录或者密码登录  如果是密钥直接读取 不用传 如果是密码就让用户输入
        try {
            $ssh = new SSH2($ip,$port);

            if (!$ssh->login($user, $rsa)) {
                return [
                    'message'=>"设备离线或者异常,无法发送消息!",
                    'code' => "-3",
                ];
            }

            $output=$ssh->exec($command);

            $output = iconv('UTF-8', 'UTF-8//IGNORE', $output);
            $ssh->disconnect();
            return [
                'message'=>$output,
                'code' => "1",
            ];
        } catch (Exception $e) {
            return [
                'message' => $e->getMessage(),
                'code' => "-2",
            ];
        }

    }
本作品采用《CC 协议》,转载必须注明作者和本文链接
chowjiawei
《L05 电商实战》
从零开发一个电商项目,功能包括电商后台、商品 & SKU 管理、购物车、订单管理、支付宝支付、微信支付、订单退款流程、优惠券等
《G01 Go 实战入门》
从零开始带你一步步开发一个 Go 博客项目,让你在最短的时间内学会使用 Go 进行编码。项目结构很大程度上参考了 Laravel。
讨论数量: 0
(= ̄ω ̄=)··· 暂无内容!

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!