如何通过本地HTML页面执行同目录Shell脚本并获取执行结果
实现本地HTML页面执行Shell脚本并获取结果
直接通过file://协议访问的普通HTML页面无法直接执行本地Shell脚本,这是浏览器的安全限制——为了防止恶意网页随意调用本地程序,浏览器会严格隔离网页与本地系统的权限,所以你用window.open('./test.sh')只会触发脚本下载,这是正常的安全行为。
要实现需求,需要借助能突破该权限限制的工具,以下是两种可行方案:
方案1:使用Electron构建桌面应用
Electron允许用HTML/JS编写界面,同时可以调用Node.js的API执行本地脚本,步骤如下:
初始化Electron项目:
确保已安装Node.js,创建项目文件夹后执行:npm init -y npm install electron --save-dev项目文件结构:
项目文件夹/ ├── index.html ├── main.js ├── test.sh └── package.json编写
main.js(Electron主进程文件):const { app, BrowserWindow, ipcMain } = require('electron'); const { execFile } = require('child_process'); const path = require('path'); let mainWindow; function createWindow() { mainWindow = new BrowserWindow({ width: 800, height: 600, webPreferences: { nodeIntegration: true, contextIsolation: false } }); mainWindow.loadFile('index.html'); } // 监听渲染进程的脚本执行请求 ipcMain.on('run-script', (event) => { const scriptPath = path.join(__dirname, 'test.sh'); execFile(scriptPath, (error, stdout, stderr) => { if (error) { event.reply('script-result', { success: false, output: stderr }); return; } event.reply('script-result', { success: true, output: stdout }); }); }); app.whenReady().then(createWindow); app.on('window-all-closed', () => { if (process.platform !== 'darwin') app.quit(); });编写
index.html(渲染进程界面):<!DOCTYPE html> <html> <body> <button id="runBtn">执行脚本</button> <div id="result"></div> <script> const { ipcRenderer } = require('electron'); const runBtn = document.getElementById('runBtn'); const resultDiv = document.getElementById('result'); runBtn.addEventListener('click', () => { ipcRenderer.send('run-script'); }); // 接收脚本执行结果并存储到变量 ipcRenderer.on('script-result', (event, data) => { let scriptResult; if (data.success) { scriptResult = data.output; resultDiv.textContent = `执行成功:\n${scriptResult}`; } else { scriptResult = data.output; resultDiv.textContent = `执行失败:\n${scriptResult}`; } console.log('脚本结果已存入变量:', scriptResult); }); </script> </body> </html>修改
package.json的启动脚本:
在package.json中添加:"scripts": { "start": "electron ." }运行项目:
npm start点击按钮即可执行
test.sh,并将执行结果存入变量。
方案2:搭建本地CGI服务器
如果不想使用Electron,可以搭建简单的本地CGI服务器,以Python的http.server为例:
给
test.sh添加可执行权限:chmod +x test.sh创建
cgi-bin文件夹,并编写Python CGI脚本cgi-bin/handler.py:#!/usr/bin/env python3 import subprocess import cgitb cgitb.enable() print("Content-Type: text/plain") print() script_path = "../test.sh" result = subprocess.run([script_path], capture_output=True, text=True) print(result.stdout if result.returncode == 0 else result.stderr)启动CGI服务器:
python3 -m http.server --cgi 8000编写
index.html(通过http://localhost:8000/index.html访问):<!DOCTYPE html> <html> <body> <button id="runBtn">执行脚本</button> <div id="result"></div> <script> const runBtn = document.getElementById('runBtn'); const resultDiv = document.getElementById('result'); runBtn.addEventListener('click', async () => { try { const response = await fetch('/cgi-bin/handler.py'); const scriptResult = await response.text(); resultDiv.textContent = `执行结果:\n${scriptResult}`; console.log('脚本结果已存入变量:', scriptResult); } catch (error) { resultDiv.textContent = `请求失败:${error.message}`; } }); </script> </body> </html>
内容的提问来源于stack exchange,提问作者Thierry J
相关产品推荐
相关产品推荐

