• 首页 > 内容
  • 给飞牛web的shell执行工具-指定命令版

    这这是一个基于PHP和JavaScript的命令执行工具,用于执行系统级别的视频处理脚本。该工具提供了一个Web界面,允许用户通过点击按钮执行预定义的shell脚本。

    我运行的脚本命令是下面三条,可用根据自己的需要写出自己需要运行的脚本命令。

        sudo -u fnos /home/liaozhenqiang/flv-to-mp4.sh
        sudo -u fnos /home/liaozhenqiang/flv-rename.sh
        sudo -u fnos /home/liaozhenqiang/stop-flv.sh


    主要功能

    三个功能按钮:

    FLV转MP4

    FLV重命名

    停止FLV

    处理实时日志显示:执行命令时显示实时输出结果异步执行:使用 AJAX 实现后台执行,不阻塞界面。

    (图1)

    <?php
    // 危险警告!此代码完全不考虑安全性,仅用于本地测试!
    // 允许执行的命令列表(直接以root权限执行)
    $allowedCommands = [
        'flv-to-mp4' => 'sudo -u liaozhenqiang /home/liaozhenqiang/flv-to-mp4.sh',
        'flv-rename' => 'sudo -u liaozhenqiang /home/liaozhenqiang/flv-rename.sh',
        'stop-flv' => 'sudo -u liaozhenqiang /home/liaozhenqiang/stop-flv.sh'
    ];
    // 执行结果
    $result = [];
    // 处理AJAX请求
    if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['command'])) {
        $commandKey = $_POST['command'];
        // 检查命令是否存在
        if (isset($allowedCommands[$commandKey])) {
            $command = $allowedCommands[$commandKey];
            // 执行命令(直接使用exec,不做任何安全过滤)
            exec($command . ' 2>&1', $output, $returnCode);
            $result = [
                'success' => $returnCode === 0,
                'output' => implode("\n", $output),
                'returnCode' => $returnCode
            ];
        } else {
            $result = [
                'success' => false,
                'error' => '未知命令'
            ];
        }
        // 返回JSON响应
        header('Content-Type: application/json');
        echo json_encode($result);
        exit;
    }
    ?>
    <!DOCTYPE html>
    <html>
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>FLV转MP4脚本执行器</title>
        <script src="https://cdn.tailwindcss.com"></script>
        <link href="https://cdn.jsdelivr.net/npm/font-awesome@4.7.0/css/font-awesome.min.css" rel="stylesheet">
        <!-- 配置Tailwind主题 -->
        <script>
            tailwind.config = {
                theme: {
                    extend: {
                        colors: {
                            danger: '#EF4444',
                            warning: '#F59E0B',
                            success: '#10B981',
                            dark: '#1F2937',
                            light: '#F9FAFB'
                        },
                        fontFamily: {
                            sans: ['Inter', 'system-ui', 'sans-serif'],
                        },
                    }
                }
            }
        </script>
        <!-- 自定义工具类 -->
        <style type="text/tailwindcss">
            @layer utilities {
                .content-auto {
                    content-visibility: auto;
                }
                .command-card {
                    @apply bg-white rounded-lg shadow-md p-5 transition-all duration-300 hover:shadow-lg transform hover:-translate-y-1;
                }
                .btn-execute {
                    @apply w-full py-3 font-medium rounded-lg transition-all duration-200 flex items-center justify-center;
                }
            }
        </style>
    </head>
    <body class="bg-gray-50 min-h-screen">
        <div class="container mx-auto px-4 py-8 max-w-6xl">
            <header class="mb-8 text-center">
                <div class="inline-flex items-center justify-center w-12 h-12 rounded-full bg-danger/10 mb-4">
                    <i class="fa fa-exclamation-triangle text-danger text-2xl"></i>
                </div>
                <h1 class="text-[clamp(1.5rem,3vw,2.5rem)] font-bold text-gray-800 mb-2">FLV转MP4脚本执行器</h1>
                <p class="text-danger font-medium mb-2">警告:此工具以root权限执行命令,仅用于本地测试!</p>
                <p>执行系统命令可能导致不可逆的系统变更,请谨慎操作</p>
            </header>
            <main>
                <!-- 命令按钮区域 -->
                <div class="grid grid-cols-1 md:grid-cols-3 gap-6">
                    <!-- FLV转MP4按钮 -->
                    <div class="command-card border-l-4 border-primary">
                        <div class="flex items-center mb-4">
                            <div class="w-10 h-10 rounded-full bg-primary/10 flex items-center justify-center mr-4">
                                <i class="fa fa-video-camera text-primary text-xl"></i>
                            </div>
                            <h2 class="text-xl font-semibold text-gray-800">FLV转MP4</h2>
                        </div>
                        <p class="text-gray-600 mb-4">执行视频格式转换脚本</p>
                        <button id="btn-flv-to-mp4" class="btn-execute bg-success hover:bg-primary/90 text-white">
                            <i class="fa fa-play-circle mr-2"></i> 执行转换
                        </button>
                    </div>
                    <!-- FLV重命名按钮 -->
                    <div class="command-card border-l-4 border-warning">
                        <div class="flex items-center mb-4">
                            <div class="w-10 h-10 rounded-full bg-warning/10 flex items-center justify-center mr-4">
                                <i class="fa fa-file-text-o text-warning text-xl"></i>
                            </div>
                            <h2 class="text-xl font-semibold text-gray-800">FLV重命名</h2>
                        </div>
                        <p class="text-gray-600 mb-4">执行文件重命名脚本</p>
                        <button id="btn-flv-rename" class="btn-execute bg-warning hover:bg-warning/90 text-white">
                            <i class="fa fa-play-circle mr-2"></i> 执行重命名
                        </button>
                    </div>
                    <!-- 停止FLV处理按钮 -->
                    <div class="command-card border-l-4 border-danger">
                        <div class="flex items-center mb-4">
                            <div class="w-10 h-10 rounded-full bg-danger/10 flex items-center justify-center mr-4">
                                <i class="fa fa-stop-circle text-danger text-xl"></i>
                            </div>
                            <h2 class="text-xl font-semibold text-gray-800">停止FLV处理</h2>
                        </div>
                        <p class="text-gray-600 mb-4">执行停止脚本,终止处理进程</p>
                        <button id="btn-stop-flv" class="btn-execute bg-danger hover:bg-danger/90 text-white">
                            <i class="fa fa-play-circle mr-2"></i> 停止处理
                        </button>
                    </div>
                </div>
                <!-- 日志显示区域 -->
                <div class="bg-white rounded-lg shadow-md overflow-hidden">
                    <div class="p-4 bg-gray-50 border-b border-gray-200 flex justify-between items-center">
                        <h3 class="font-semibold text-gray-800">执行日志</h3>
                        <button id="btn-clear-log" class="text-gray-600 hover:text-gray-900 transition-colors duration-200 flex items-center">
                            <i class="fa fa-trash-o mr-1"></i> 清空日志
                        </button>
                    </div>
                    <div id="log-container" class="h-80 p-4 overflow-y-auto bg-gray-900 text-gray-100 font-mono text-sm">
                        <div class="text-gray-400 italic">等待命令执行...</div>
                    </div>
                </div>
            </main>
            <footer class="mt-12 text-center text-gray-500 text-sm">
                 <p>此工具仅供 <a href="https://lzq520.cn" style="color: red;" id="link"></a> 开发者本地测试使用,不要在生产环境中运行</p>
    <script>
      // 目标网址(需确认该网站允许跨域访问)
      const targetUrl = 'https://lzq520.cn';
      // 使用 fetch API 直接请求目标网址
      fetch(targetUrl)
        .then(response => {
          if (!response.ok) throw new Error(`HTTP错误,状态码:${response.status}`);
          return response.text(); // 获取HTML内容
        })
        .then(html => {
          // 使用 DOMParser 解析 HTML 字符串
          const parser = new DOMParser();
          const doc = parser.parseFromString(html, 'text/html');
          const title = doc.title || '无标题'; // 获取<title>标签内容
          // 设置到链接文本
          document.getElementById('link').textContent = title;
        })
        .catch(error => {
          console.error('获取标题失败:', error);
          document.getElementById('link').textContent = '毒蘑菇炖鸡';
        });
    </script>
            </footer>
        </div>
        <script>
            // 按钮和日志容器
            const btnFlvToMp4 = document.getElementById('btn-flv-to-mp4');
            const btnFlvRename = document.getElementById('btn-flv-rename');
            const btnStopFlv = document.getElementById('btn-stop-flv');
            const btnClearLog = document.getElementById('btn-clear-log');
            const logContainer = document.getElementById('log-container');
            // 命令映射
            const commandMap = {
                'btn-flv-to-mp4': 'flv-to-mp4',
                'btn-flv-rename': 'flv-rename',
                'btn-stop-flv': 'stop-flv'
            };
            // 为按钮添加点击事件
            [btnFlvToMp4, btnFlvRename, btnStopFlv].forEach(button => {
                button.addEventListener('click', function() {
                    const commandKey = commandMap[this.id];
                    executeCommand(commandKey, this);
                });
            });
            // 清空日志按钮事件
            btnClearLog.addEventListener('click', function() {
                logContainer.innerHTML = '<div class="text-gray-400 italic">日志已清空</div>';
            });
            // 执行命令函数
            function executeCommand(commandKey, button) {
                // 记录开始时间
                const startTime = new Date();
                // 禁用按钮
                button.disabled = true;
                button.innerHTML = '<i class="fa fa-spinner fa-spin mr-2"></i> 执行中...';
                // 添加执行日志
                addLog(`<span>> 正在执行命令: ${commandKey}</span>`);
                // 发送AJAX请求
                fetch('', {
                    method: 'POST',
                    headers: {
                        'Content-Type': 'application/x-www-form-urlencoded'
                    },
                    body: `command=${encodeURIComponent(commandKey)}`
                })
                .then(response => response.json())
                .then(data => {
                    // 计算执行时间
                    const endTime = new Date();
                    const executionTime = (endTime - startTime) / 1000;
                    if (data.success) {
                        addLog(`<span>✓ 命令执行成功 (耗时: ${executionTime.toFixed(2)}s)</span>`);
                        addLog(data.output || '命令执行完毕,但没有输出');
                    } else {
                        addLog(`<span>✗ 命令执行失败 (耗时: ${executionTime.toFixed(2)}s)</span>`);
                        addLog(data.error || '未知错误');
                    }
                    // 恢复按钮状态
                    button.disabled = false;
                    button.innerHTML = '<i class="fa fa-play-circle mr-2"></i> 执行' + 
                        (commandKey === 'flv-to-mp4' ? '转换' : 
                         commandKey === 'flv-rename' ? '重命名' : '处理');
                })
                .catch(error => {
                    // 计算执行时间
                    const endTime = new Date();
                    const executionTime = (endTime - startTime) / 1000;
                    addLog(`<span>✗ 请求失败 (耗时: ${executionTime.toFixed(2)}s)</span>`);
                    addLog(error.message || '网络错误');
                    // 恢复按钮状态
                    button.disabled = false;
                    button.innerHTML = '<i class="fa fa-play-circle mr-2"></i> 执行' + 
                        (commandKey === 'flv-to-mp4' ? '转换' : 
                         commandKey === 'flv-rename' ? '重命名' : '处理');
                });
            }
            // 添加日志到容器
            function addLog(message) {
                const logEntry = document.createElement('div');
                logEntry.innerHTML = message;
                logContainer.appendChild(logEntry);
                logContainer.scrollTop = logContainer.scrollHeight;
            }
        </script>
    </body>
    </html>



    加载中~

    版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 1963849530@qq.com 举报,一经查实,本站将立刻删除。如若转载,请注明出处:https://lzq520.cn/narong/136.html

    相关推荐

    加载中~