You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何实现点击按钮根据用户输入执行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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 07:27:15