在分佈式環境中,常需要將同一個文件快速分發到多台伺服器。本文介紹一個基於 libssh2 庫的命令列工具 mooon_upload,可通過 SSH 協議將本地文件並行上傳到多台目標主機的指定目錄。
./mooon_upload -h=192.168.10.11,192.168.10.12 -p=6000 -u=root -P='root123' -s=./abc -d=/tmp/
上述命令將本地文件 ./abc 上傳到兩台主機 192.168.10.11 和 192.168.10.12 的 /tmp/ 目錄下。參數說明:
-h:目標主機 IP 列表,逗號分隔-p:SSH 端口(預設 22)-u:登入用戶名(預設 root)-P:登入密碼-s:本地源文件路徑-d:遠端存放目錄-t:連接超時秒數(預設 10)工具使用 mooon 框架的組件:
mooon::net::CLibssh2:封裝 libssh2 的 SSH 連接與文件傳輸mooon::utils::CArgsParser:命令列參數解析mooon::sys::CStopWatch:計時統計傳輸耗時mooon::utils::CTokener:字符串分割(解析主機列表)HOSTS 讀取主機列表。CTokener::split 將逗號分隔的 IP 字符串轉為向量。CLibssh2 連接,調用 upload() 傳輸文件,捕獲異常並記錄結果。ResultInfo 結構體記錄每台主機的成功/失敗狀態及耗時,最後輸出匯總報告。for (int i = 0; i < num_remote_hosts_ip; ++i) {
const std::string& remote_host_ip = hosts_ip[i];
results[i].ip = remote_host_ip;
results[i].success = false;
mooon::sys::CStopWatch stop_watch;
try {
int file_size = 0;
mooon::net::CLibssh2 libssh2(remote_host_ip, port, user, password, timeout);
libssh2.upload(source, remote_filepath, &file_size);
results[i].success = true;
fprintf(stdout, "[%s] SUCCESS: %d bytes\n", remote_host_ip.c_str(), file_size);
} catch (mooon::sys::CSyscallException& ex) {
fprintf(stderr, "[%s] failed: %s\n", remote_host_ip.c_str(), ex.str().c_str());
} catch (mooon::utils::CException& ex) {
fprintf(stderr, "[%s] failed: %s\n", remote_host_ip.c_str(), ex.str().c_str());
}
results[i].seconds = stop_watch.get_elapsed_microseconds() / 1000000;
}
================================
[192.168.10.11 SUCCESS]: 2 seconds
[192.168.10.12 SUCCESS]: 3 seconds
SUCCESS: 2, FAILURE: 0
此工具適合自動化部署腳本、集群配置分發等場景,代碼結構清晰,易於擴展支持密鑰認證、斷點續傳等功能。