首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> JSP 程式設計 >> 關於JSP

JSP 呼叫 Linux Shell 腳本實作:Runtime.exec 非同步執行與輸出捕獲

     編輯:關於JSP

運維常需清理快取、重啟服務等操作,若能透過 Web 頁面觸發 Shell 腳本,將大幅降低人工成本。本文示範 JSP 以 Runtime.getRuntime().exec() 呼叫 Linux 腳本,並即時讀取標準輸出顯示於頁面。

JSP 完整程式碼

<%@ page import="java.io.*" pageEncoding="UTF-8" %>
<html><body>
<%
    String script = "/opt/wzx/monitor.sh"; // 絕對路徑,確保權限
    try {
        Process proc = Runtime.getRuntime().exec(new String[]{"sh", script});
        // 捕獲標準輸出
        BufferedReader br = new BufferedReader(
            new InputStreamReader(proc.getInputStream(), "UTF-8"));
        String line;
        proc.waitFor(); // 等待結束(或改非阻塞輪詢)
        while ((line = br.readLine()) != null) {
            out.print(line);
            out.print("<br/>");
        }
        br.close();
    } catch (Exception e) {
        e.printStackTrace(out);
    }
%>
</body></html>

Shell 腳本範例 monitor.sh

#!/bin/bash
echo 'flush_all' | nc 192.168.10.73 11211  # 清 Memcached
echo "Cache flushed at $(date)"

記得 chmod +x monitor.sh,並確保執行 JSP 的使用者(如 tomcat)對腳本有執行權限。

關鍵細節與最佳實踐

  • 絕對路徑:exec 不會載入 Shell 環境變數,命令與腳本皆用完整路徑。
  • 陣列形式 exec:exec(new String[]{"sh", script}) 避免空白/特殊字元解析問題。
  • 雙向流處理:若腳本產生大量輸出,必須同時讀取 getInputStream() 與 getErrorStream()**(建議用兩條執行緒),否則管道塞滿導致進程卡死。
  • 非阻塞/超時:生產環境勿直接 waitFor() 卡住請求執行緒,改用 CompletableFuture 或排程器非同步執行,頁面回傳任務 ID,前端輪詢狀態。
  • 安全性:嚴格驗證請求來源(IP 白名單、Token、角色),避免任意命令執行漏洞。
  • 編碼:InputStreamReader(proc.getInputStream(), "UTF-8") 明確指定編碼,防止中文亂碼。

進階替代方案

  • SSH 執行:用 JSch/SSHJ 遠端執行,隔離 Web 與應用主機。
  • 訊息佇列:Web 發送指令至 RabbitMQ/Kafka,Agent 訂閱執行並回報結果,解耦且可追蹤。
  • Ansible/SaltStack API:透過自動化運維平台 API 觸發 Playbook,更標準可控。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved