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

Linux 下主機遠程操作備機目錄與文件:system vs popen 實現詳解

     編輯:關於C語言

需求場景

主機 A 需在程式中遠程控制備機 B:創建目錄、複製文件。程式運行在 A,操作作用於 B。

核心思路:管道 + telnet 自動化交互

利用 Shell 管道將交互命令(登錄、輸入密碼、執行操作)流式傳輸給 `telnet` 客戶端:

(sleep 0.5; echo "user"; sleep 1; echo "pass"; sleep 5; echo "cd /path; mkdir -p dir; cp file dir/"; sleep 2) | telnet 10.10.10.10
  • `sleep`:等待提示符出現,同步節奏。
  • `echo`:發送用戶名、密碼、具體命令。
  • 括號 `(...)`:將命令序列作為一個整體輸出流。

方案一:`system()` 函數

void DealRemoteFile(void) {
    char cmd[1024];
    snprintf(cmd, sizeof(cmd)-1,
        "(sleep 0.5; echo zhou; sleep 1; echo zhou; sleep 5; "
        "echo \"cd /home/zhou/zhouzx/Test; mkdir -p TestFile; cp TestFile.txt ./TestFile;\"; sleep 2) | telnet 10.10.10.10");
    system(cmd); // 同步阻塞執行,無法捕獲輸出
}

缺點:無法獲取遠程命令輸出/錯誤信息,難以判斷執行成敗。

方案二:`popen()` / `pclose()` 管道流(推薦)

void DealRemoteFile(void) {
    char cmd[1024], result[1024];
    snprintf(cmd, sizeof(cmd)-1, /* 同樣的命令字符串 */);
    FILE *fp = popen(cmd, "r"); // 打開管道,以讀模式獲取標準輸出
    if (!fp) return;
    while (fgets(result, sizeof(result), fp)) {
        // 處理每行輸出,如去除換行符、日誌記錄
        result[strcspn(result, "\n")] = '\0';
        printf("Remote output: %s\n", result);
    }
    pclose(fp); // 必須配對關閉,回收子進程資源
}

優勢:可讀取遠程命令的標準輸出/錯誤輸出,實現結果驗證與日誌審計。

關鍵技術點總結

維度system()popen()/pclose()
返回值Shell 退出碼文件指鉤,可讀輸出流
同步性阻塞等待阻塞讀取,流結束自動回收
適用場景無需反饋的火燭忘操作需捕獲輸出、判斷成敗的場景
底層機制fork + exec + waitfork + pipe + exec,父進程持有管道端

安全與工程化建議

  1. 避免明文密碼:生產環境應使用 SSH 密鑰認證或 `sshpass`,而非 telnet 明文傳輸。
  2. 超時控制:`telnet` 可能掛起,建議結合 `alarm`/`select`/`expect` 工具實現超時機制。
  3. 錯誤碼檢查:解析遠程輸出中的錯誤關鍵字(`Permission denied`、`No such file` 等)。
  4. 優先選 SSH:`ssh user@host "cmd"` 更安全、標準、支持管道傳輸標準輸入輸出。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved