如何实现点击按钮根据用户输入执行Linux Bash命令
实现方案说明
首先明确核心限制:浏览器环境下运行的前端JavaScript受沙箱安全机制约束,没有权限直接调用宿主Linux系统的shell执行命令,直接在原有前端JS里改逻辑无法实现该需求,可选择以下几种可行落地方案:
方案1:本地轻量后端转发(最稳妥推荐)
用Python/Node.js在本地起一个极简后端服务,前端点击按钮时把拼接好的命令发给后端,由后端代执行系统命令,步骤如下:
- 先修改前端
execute函数逻辑,不再渲染文本,改为把命令通过POST请求发给本地后端:
async function execute(){ const cmd = "asusctl fan-curve -m " + mode.value + " -D " + "30c:"+ num3.value + ",40C:" + num4.value + " -e true -f "+ unit.value; // 发给本地后端接口,示例服务开在6789端口 const resp = await fetch("http://127.0.0.1:6789/run-cmd", { method: "POST", headers: {"Content-Type": "application/json"}, body: JSON.stringify({command: cmd}) }); const res = await resp.json(); // 把执行结果回显到result元素 document.getElementById("result").textContent = res.code === 0 ? `执行成功:\n${res.stdout}` : `执行失败:\n${res.stderr}`; }
- 写一个极简的Python后端示例(保存为
server.py,执行pip install fastapi uvicorn安装依赖后,用sudo python server.py启动,因为asusctl操作风扇曲线需要root权限):
from fastapi import FastAPI, Body from fastapi.middleware.cors import CORSMiddleware import subprocess app = FastAPI() # 允许本地前端跨域请求 app.add_middleware( CORSMiddleware, allow_origins=["*"], allow_credentials=True, allow_methods=["*"], allow_headers=["*"], ) @app.post("/run-cmd") def run_cmd(command: dict = Body(...)): # 安全校验:仅允许执行asusctl开头的命令,防范任意命令执行漏洞 if not command["command"].startswith("asusctl"): return {"code": -1, "stdout": "", "stderr": "非法命令,已拦截"} result = subprocess.run(command["command"], shell=True, capture_output=True, text=True) return {"code": result.returncode, "stdout": result.stdout, "stderr": result.stderr} if __name__ == "__main__": import uvicorn uvicorn.run(app, host="127.0.0.1", port=6789)
方案2:打包成本地桌面应用
用Tauri/Electron把现有前端页面打包成本地桌面应用,这类框架可以给前端开放调用系统命令的权限:
- 选Tauri的话,直接在前端调用Tauri提供的shell API执行命令即可,打包后无需额外启动后端,体积小性能好
- 选Electron的话,在主进程暴露执行命令的IPC接口给渲染进程调用即可,注意配置权限白名单,仅允许执行asusctl相关命令,避免安全风险
方案3:生成可执行脚本手动运行(零额外依赖)
如果不想写后端/打包应用,可以保留原有命令生成逻辑,把生成的命令自动封装为可下载的shell脚本,用户点击按钮下载脚本后执行即可:
function execute(){ const cmd = "asusctl fan-curve -m " + mode.value + " -D " + "30c:"+ num3.value + ",40C:" + num4.value + " -e true -f "+ unit.value; const scriptContent = `#!/bin/bash\n${cmd}\necho "执行完成,按任意键退出"\nread -n 1`; const blob = new Blob([scriptContent], {type: "text/x-shellscript"}); const url = URL.createObjectURL(blob); const a = document.createElement("a"); a.href = url; a.download = "set-fan-curve.sh"; a.click(); URL.revokeObjectURL(url); document.getElementById("result").textContent = "脚本已下载,给脚本添加执行权限后用sudo运行即可"; }
注意:asusctl修改风扇曲线需要root权限,所有执行方案都要处理权限问题,否则命令会执行失败。
原有代码参考
HTML部分
编写的两组输入控件代码如下:
<input id="range3" type="range" min="0" max="255" value="0" /> <input id="num3" min="0" max="255" type="number" value="0" /> <input id="range4" type="range" min="0" max="255" value="0" /> <input id="num4" min="0" max="255" type="number" value="0" />
原有JS逻辑
已实现滑块与数字输入双向同步,原execute函数仅做命令文本渲染:
// 30度对应风扇值双向同步 var range3 = document.getElementById("range3"); var num3 = document.getElementById('num3'); range3.addEventListener('input', function (e) { num3.value = e.target.value; }); num3.addEventListener('input', function (e) { range3.value = e.target.value; }); // 40度对应风扇值双向同步 var range4 = document.getElementById("range4"); var num4 = document.getElementById('num4'); range4.addEventListener('input', function (e) { num4.value = e.target.value; }); num4.addEventListener('input', function (e) { range4.value = e.target.value; }); function execute(){ document.getElementById("result").innerHTML = "asusctl fan-curve -m " + mode.value + " -D " + "30c:"+ num3.value + ",40C:" + num4.value + " -e true -f "+ unit.value ; }
内容的提问来源于stack exchange,提问作者Gurjant Singh
相关产品推荐
相关产品推荐

