【bash】2、手把手實現一個 bash shell:多個機器批量執行 shell 命令,支持 ip 補全

文章目錄

  • 一、需求:多臺機器批量遠程執行 shell 命令
    • 1.1 業務需求拆解為腳本需求
    • 1.2 幫助函數:使用說明文檔
    • 1.3 main 函數框架
  • 二、功能:單機 sshp 執行
    • 2.1 fullip 函數:實現 ip 補全
      • 2.1.1 參數說明
      • 2.1.2 定義全局變量
      • 2.1.3 實現:正則匹配、if 分支
      • 2.1.4 測試
    • 2.2 sshp 函數
      • 2.2.1 參數說明
      • 2.2.2 定義全局變量
      • 2.2.3 實現:利用 sshpass 傳參
      • 2.2.4 測試
  • 三、功能:多機批量 batch_sshp 執行
    • 3.1 batch_sshp 函數:多機 sshp 執行
      • 3.1.1 參數說明
      • 3.1.2 實現
        • 3.1.2.1 利用 awk 分隔一個參數
        • 3.1.2.2 利用 awk 分隔多個參數
        • 3.1.2.3 批量執行腳本
      • 3.1.3 測試、使用示例
        • 3.1.3.1 執行 ls 查看目錄
        • 3.1.3.2 執行 df 查看磁盤占用率
      • 3.1.4 完整腳本

一、需求:多臺機器批量遠程執行 shell 命令

這個腳本可以執行任何命令,用途是廣泛的,例如執行 ls 查看目錄,或執行 df 查看磁盤占用率

1.1 業務需求拆解為腳本需求

首先可以寫 shell 批量獲取各機器的磁盤占用率,通過在各機器執行 df -h | head 實現

希望的使用示例為:

mgr.sh 2.99 2.100 df -h | head

1.2 幫助函數:使用說明文檔

首先寫 print_help()

 # print_helpprint_help() {cat << EOF$0ssh IP1 IP2 ... [cmd]            -- ssh 連接 IP,執行 cmdfullip SUFFIX_IP                 -- 獲取完整的 IP 地址EOFexit}

1.3 main 函數框架

然后寫 main 函數

# maincase $1 inssh)shiftsshp "$@";;fullip)shiftfullip "$@";;*)print_help;;esac

二、功能:單機 sshp 執行

2.1 fullip 函數:實現 ip 補全

2.1.1 參數說明

然后實現 fullip 函數,先寫改函數的參數說明:

 # fullip# 根據 ip 后綴,補全完整的 ip 地址# 參數$1 為 ip 地址的后綴fullip() {}

2.1.2 定義全局變量

然后在文件開頭,定義全局變量 ip_prefix=192.168

# 全局信息
# ip 前綴
PRE_IP=192.168

2.1.3 實現:正則匹配、if 分支

然后實現 fullip 函數

 # 全局信息# ip 前綴PRE_IP=192.168# fullip# 根據 ip 后綴,補全完整的 ip 地址# 參數$1 為 ip 地址的后綴fullip() {[ "x$1" == "x" ] && echo "Error: 請輸入 IP 后綴" && exit 10# 已經是完整的 ip 地址if [[ $1 =~ ^([0-9]{1,3}\.){3}[0-9]{1,3}$ ]]; thenecho $1return# 只有 2 位的ip 后綴elif[[ $1 =~ ^[0-9]{1,3}\.[0-9]{1,3}$ ]]; then# 補全完整的 ip 地址echo $PRE_IP.$1returnelseecho -e "Error: 請輸入正確的 IP 后綴"exit 101fi}

2.1.4 測試

然后測試腳本, 一切正常:

# 先執行腳本,不輸入參數
./mgr.sh
./mgr.shssh IP1 IP2 ... [cmd]            -- ssh 連接 IP,執行 cmdfullip SUFFIX_IP                 -- 獲取完整的 IP 地址# 再執行 fullip,輸入全量 ip
./mgr.sh fullip 192.168.2.1
192.168.2.1# 再執行 fullip,輸入ip 后綴
./mgr.sh fullip 2.99
192.168.2.99

2.2 sshp 函數

然后,寫 sshp 函數,通過 sshpass 遠程執行命令

2.2.1 參數說明

首先寫參數說明

# sshp: 通過 sshpass 執行遠程命令
# $1 是補全的 ip
# ssh 協議的用戶名和密碼,是寫死的全局變量
# $@ 是ssh 需執行的 cmd

然后補全函數聲明, 其實 shell 函數都是形如 f() {} 的

# sshp: 通過 sshpass 執行遠程命令
# $參數 $1 為 ip 地址, 和 shell 的 $1 是一樣的,可能是完整的 ip,也可能是 ip 的后綴
# ssh 協議的用戶名和密碼,是寫死的全局變量
# $@ 是ssh 需執行的 cmd
sshp() {}

2.2.2 定義全局變量

然后,定義全局變量,即 ssh 的用戶名和密碼。

這取決于需求,如果所操作的機器的用戶名和密碼都是相同的,則可以寫死為全局變量。否則可以在腳本參數中輸入。

USER=ubuntu
PASSWORD=ubuntu

2.2.3 實現:利用 sshpass 傳參

 sshp() {sshpass -p $PASSWORD ssh -o StrictHostKeyChecking=no "$USER"@$1 "$@"}

注意,sshpass 是 main 函數的入口,所以其輸入的參數 $1 就是整個 shell 的 參數 $1。

而 $1 雖然是 ip,但可能是完整的 ip 或者 僅 ip 后綴。

所以需要在 sshp() 做兩步工作:

  1. 內調用 fullip() 實現 ip 的補全
  2. 將補全的 ip 傳參給 sshpass

因此改寫為如下:

 # sshp# 利用 sshpass 連接到指定的 ip 地址,并執行命令# 參數 $1 為 ip 地址, 和 shell 的 $1 是一樣的,可能是完整的 ip,也可能是 ip 的后#綴sshp() {local remote=$(fullip $1)echo -e "remote is: $remote"# 注意解析完 $1 后,則需要 shift,以便解析后續參數shiftsshpass -p $PASSWORD ssh -o StrictHostKeyChecking=no "$USER"@${remote} "$@"}

2.2.4 測試

# 打印幫助信息
$ ./mgr.sh
./mgr.shssh IP1 IP2 ... [cmd]            -- ssh 連接 IP,執行 cmdfullip SUFFIX_IP                 -- 獲取完整的 IP 地址# 遠程 ssh 執行一個命令
$ ./mgr.sh ssh 2.99 ls
remote is: 192.168.299
a.txt
b.json

三、功能:多機批量 batch_sshp 執行

3.1 batch_sshp 函數:多機 sshp 執行

需求拆解:

多機 sshp 批量執行,因為要多個機器執行,所以需要填多個 ip,例如以空格分隔

因此 ips 和 cmd 之間要有明確的分隔符,例如 cmd

3.1.1 參數說明

./mgr.sh batch_ssh < ip | ip_suffix …> cmd

# 首先解析 ip 列表
# 其次解析 shell-cmds(通過 cmd 關鍵字)
bahch_ssh() {}

思路:利用 awk 分隔參數

首先,main 解析 $1,如果是 “batch_ssh”,則執行 batch_ssh() 并將參數 shift

然后,用 awk 按 cmd 關鍵字,拆分參數為 ips 和 shell-cmd,存儲到兩個 local 變量里

其次,for ip in ips 遍歷得到 ip 列表,每次循環都執行一次 sshp 函數

而,shell-cmd 變量則無需解析,直接在 sshp 函數使用即可

所以,完善的函數聲明如下:

# batch_ssh
# 對多個機器,批量執行命令
# 根據 "cmd" 關鍵字,將命令分成兩部分,前一部分是 ips 地址數組,后一部分是命令
# 用 for 遍歷 ips 數組,對每個 ip 執行命令
batch_ssh() {}

3.1.2 實現

3.1.2.1 利用 awk 分隔一個參數
# batch_ssh
# 對多個機器,批量執行命令
# 根據 "cmd" 關鍵字,將命令分成兩部分,前一部分是 ips 地址數組,后一部分是命令
# 用 for 遍歷 ips 數組,對每個 ip 執行命令batch_ssh() {local ips=$(echo "$@" | awk -F 'cmd' '{print $1}')echo -e "ips: ${ips}"echo -e "ips: ${ips[@]}"}

測試:

./mgr.sh batch_ssh 2.99 2.100
ips: 2.99 2.100
ips: 2.99 2.100
3.1.2.2 利用 awk 分隔多個參數
 batch_ssh() {local ips=$(echo "$@" | awk -F 'cmd' '{print $1}')local shellcmds=$(echo "$@" | awk -F 'cmd' '{print $2}')echo -e "ips: ${ips}"echo -e "shellcmds: ${shellcmds}"}

測試:

./mgr.sh batch_ssh 2.99 2.100 cmd ls -lrt
ips: 2.99 2.100
shellcmds:  ls -lrt
3.1.2.3 批量執行腳本
 batch_ssh() {local ips=$(echo "$@" | awk -F 'cmd' '{print $1}')local shellcmd=$(echo "$@" | awk -F 'cmd' '{print $2}')echo -e "ips: ${ips}"echo -e "shellcmds: ${shellcmd}"for ip in ${ips}; dolocal remote=$(fullip $ip)echo -e "\n-----開始執行: $remote-----"sshp $remote $shellcmddoneecho -e "執行完畢"}

并補全幫助信息

 # print_helpprint_help() {cat << EOF$0ssh < IP | IPSUFFIX ...> <shellcmd>            -- ssh 連接 IP,執行 cmdbatch_ssh < IP | IPSUFFIX ...> cmd <shellcmd>  -- 對多個機器,批量執行命令fullip SUFFIX_IP                               -- 獲取完整的 IP 地址EOFexit}

3.1.3 測試、使用示例

這個腳本可以執行任何命令,用途是廣泛的

3.1.3.1 執行 ls 查看目錄
./mgr.sh batch_ssh 2.99 2.100 cmd ls -lrt
ips: 2.99 2.100
shellcmds:  ls -lrt-----開始執行: 192.168.2.99-----
remote is: 192.168.2.99
a.txt
b.json-----開始執行: 192.168.2.100-----
remote is: 192.168.2.100
c.json
d.ini執行完畢
3.1.3.2 執行 df 查看磁盤占用率
mgr.sh batch_ssh 2.99 2.100 cmd df -h
ips: 2.99 2.100
shellcmds:  df -h-----開始執行: 192.168.2.99-----
remote is: 192.168.2.99
Filesystem      Size  Used Avail Use% Mounted on
udev             16G     0   16G   0% /dev
tmpfs           3.2G  1.8M  3.2G   1% /run
/dev/vda2        49G   25G   22G  54% /-----開始執行: 192.168.2.100-----
remote is: 192.168.2.100
Filesystem      Size  Used Avail Use% Mounted on
udev             48G     0   48G   0% /dev
tmpfs           9.5G  899M  8.6G  10% /run
/dev/sda1       117G   68G   44G  61% /執行完畢

3.1.4 完整腳本

#!/bin/bash# 全局信息
# ip 前綴
PRE_IP=192.168
USER=ubuntu
PASSWORD=ubuntu# fullip
# 根據 ip 后綴,補全完整的 ip 地址
# 參數$1 為 ip 地址的后綴
fullip() {[ "x$1" == "x" ] && echo "Error: 請輸入 IP 后綴" && exit 10# 已經是完整的 ip 地址if [[ $1 =~ ^([0-9]{1,3}\.){3}[0-9]{1,3}$ ]]; thenecho $1return# 只有 2 位的ip 后綴elif[[ $1 =~ ^[0-9]{1,3}\.[0-9]{1,3}$ ]]; then# 補全完整的 ip 地址echo ${PRE_IP}.$1returnelseecho -e "Error: 請輸入正確的 IP 后綴"exit 101fi
}# sshp
# 利用 sshpass 連接到指定的 ip 地址,并執行命令
# 參數 $1 為 ip 地址, 和 shell 的 $1 是一樣的,可能是完整的 ip,也可能是 ip 的后#綴
sshp() {local remote=$(fullip $1)echo -e "remote is: $remote"shiftsshpass -p $PASSWORD ssh -o StrictHostKeyChecking=no "$USER"@${remote} "$@"
}# batch_ssh
# 對多個機器,批量執行命令
# 根據 "cmd" 關鍵字,將命令分成兩部分,前一部分是 ips 地址數組,后一部分是命令
# 用 for 遍歷 ips 數組,對每個 ip 執行命令
batch_ssh() {local ips=$(echo "$@" | awk -F 'cmd' '{print $1}')local shellcmd=$(echo "$@" | awk -F 'cmd' '{print $2}')echo -e "ips: ${ips}"echo -e "shellcmds: ${shellcmd}"for ip in ${ips}; dolocal remote=$(fullip $ip)echo -e "\n-----開始執行: $remote-----"sshp $remote $shellcmddoneecho -e "\n執行完畢"
}# print_help
print_help() {
cat << EOF
$0ssh < IP | IPSUFFIX ...> <shellcmd>            -- ssh 連接 IP,執行 cmdbatch_ssh < IP | IPSUFFIX ...> cmd <shellcmd>  -- 對多個機器,批量執行命令fullip SUFFIX_IP                               -- 獲取完整的 IP 地址
EOF
exit
}# main
case $1 inssh)shiftsshp "$@";;batch_ssh)shiftbatch_ssh "$@";;fullip)shiftfullip "$@";;*)print_help;;
esac

執行效果

$ ./mgr.sh
./mgr.shssh < IP | IPSUFFIX ...> <shellcmd>            -- ssh 連接 IP,執行 cmdbatch_ssh < IP | IPSUFFIX ...> cmd <shellcmd>  -- 對多個機器,批量執行命令fullip SUFFIX_IP

環境配置:通常會在 vim 寫 shell 腳本,可以用開源的 vimrc 配置 https://github.com/amix/vimrc 替我們解決高亮等美觀問題,提升效率

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/711551.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/711551.shtml
英文地址,請注明出處:http://en.pswp.cn/news/711551.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Cu-HCP-H035 Cu-HCP-R250銅合金高精度零部件

Cu-HCP-H035 Cu-HCP-R250銅合金高精度零部件 CDA102-3/4H EN1982-CC333G EN1982-CC492K BS1400-LG4 EN1982-CC491K BS1400-LG2 CuNi18Zn19Pb1/CW408J CuNi12Zn38Mn5Pb2/CW407J CuNi12Zn30Pb1/CW406J CuNi12Zn29/CW405J CuNi12Zn25Pb1/CW404J CuNi10Zn42Pb2/CW402J CuNi10Zn27/C…

Pytorch 復習總結 4

Pytorch 復習總結&#xff0c;僅供筆者使用&#xff0c;參考教材&#xff1a; 《動手學深度學習》Stanford University: Practical Machine Learning 本文主要內容為&#xff1a;Pytorch 深度學習計算。 本文先介紹了深度學習中自定義層和塊的方法&#xff0c;然后介紹了一些…

基于Beego 1.12.3的簡單website實現

參考 用Beego開發web應用 https://www.cnblogs.com/zhangweizhong/p/10919672.htmlBeego官網 Homepage - beego: simple & powerful Go app frameworkbuild-web-application-with-golang https://github.com/astaxie/build-web-application-with-golang/blob/master/zh/pr…

源碼的角度分析Vue2數據雙向綁定原理

什么是雙向綁定 我們先從單向綁定切入&#xff0c;其實單向綁定非常簡單&#xff0c;就是把Model綁定到View&#xff0c;當我們用JavaScript代碼更新Model時&#xff0c;View就會自動更新。那么雙向綁定就可以從此聯想到&#xff0c;即在單向綁定的基礎上&#xff0c;用戶更新…

微信開發者工具-代碼管理和碼云Github遠程倉庫集成

目錄 思考&#xff1a;IDE如何進行代碼管理 代碼管理方式 一、自身提供服務 二、Git 擴展 1、環境準備 2、創建項目代碼 3、進行項目Git初始化 4、在碼云新建遠程倉庫 5、將項目進行遠程倉庫關聯 三、SVN擴展 四、代碼管理 思考&#xff1a;IDE如何進行代碼管理 初識開…

服務器部署測試環境回顧與改進建議

任務概述&#xff1a; 原計劃在2小時內完成的任務&#xff0c;由于遇到一系列挑戰&#xff0c;最終耗時1.5天。任務目標是在無外網環境的服務器上建立測試環境&#xff0c;涉及將SSD硬盤數據遷移至服務器、SSH連接、運行測試程序并監控服務器功耗。 高效實施策略&#xff1a;…

fs讀取目錄、文件

fs讀取文件 process.cwd() 是 Node.js 中的一個方法&#xff0c;它返回 Node.js 進程的當前工作目錄。這個工作目錄通常是啟動 Node.js 進程時所在的目錄。 const fs require(fs); const path require(path);// 讀取指定目錄 const configPath path.join(process.cwd(), c…

StarRocks實戰——貝殼找房數倉實踐

目錄 前言 一、StarRocks在貝殼的應用現狀 1.1 歷史的數據分析架構 1.2 OLAP選型 1.2.1 離線場景 1.2.2 實時場景 1.2.3 StarRocks 的引入 二、StarRocks 在貝殼的分析實踐 2.1 指標分析 2.2 實時業務 2.3 可視化分析 三、未來規劃 3.1 StarRocks集群的穩定性 3…

PMP考試培訓費用多少錢?

PMP考試的相關費用包括報名費用、培訓費用和證書續證費用三個部分。 一、PMP考試報名費用&#xff1a; 首次報考費用為3900元&#xff0c;如果未通過考試可以在英文報名有效期內進行補考報名&#xff0c;補考費用為2500元。 付費方式是在項目管理學會官方網站上提交報考資料…

企業數字化轉型的第一步:由被動多云向主動多云轉變

隨著經濟環境、市場形勢、技術發展、用戶需求等諸多因素的變化&#xff0c;數字化轉型為企業進一步提升效率和競爭力、提供更加豐富的個性化產品和服務、進行業務場景創新、探尋新的增長機會和運營模式提供了嶄新的途徑。越來越多的企業意識到&#xff0c;數字化轉型已不是企業…

第1篇 Linux Docker安裝rabbitmq

Docker安裝RabbitMq 1、搜索rabbitmq鏡像 docker search rabbitmq2、下載rabbitmq鏡像 docker pull rabbitmq3、運行rabbitmq服務 docker run -d --name rabbitmq --restart always -p 15672:15672 -p 5672:5672 rabbitmq4、訪問rabbitmq http://192.168.1.x:15672 5、rab…

亞信安慧AntDB:打破數據孤島,實現實時處理

AntDB數據庫以其獨特的創新能力在分布式數據庫領域引領潮流。其中&#xff0c;融合統一與實時處理是其兩大核心創新能力&#xff0c;為其贏得廣泛關注與贊譽。融合統一意味著AntDB能夠將多種不同類型的數據庫融合為一體&#xff0c;實現數據的統一管理與處理&#xff0c;極大地…

電視盒子什么品牌好?資深數碼粉強推口碑電視盒子推薦

我對各類數碼產品是非常熟悉的&#xff0c;尤其是電視盒子&#xff0c;用過超十五款了&#xff0c;涵蓋了各個主流品牌&#xff0c;最近看到很多朋友在討論不知道電視盒子什么品牌好&#xff0c;我這次要來分享的就是口碑最好的五款電視盒子推薦給各位不懂如何選電視盒子的新手…

AI、AIGC、AGI、ChatGPT它們的區別?

今天咱們聊點熱門話題&#xff0c;來點科普時間——AI、AIGC、AGI和ChatGPT到底是啥&#xff1f;這幾個詞聽起來好像挺神秘的&#xff0c;但其實它們就在我們生活中。讓我們一起探索這些術語的奧秘&#xff01; AI&#xff08;人工智能&#xff09;&#xff1a;先說說AI&#…

數倉技術選型特點

高性能&#xff1a;用全并行的MPP架構數據庫&#xff0c;業務數據被分散存儲在多個節點上&#xff0c;數據分析任務被推送到數據所在位置就近執行&#xff0c;并行地完成大規模的數據處理工作&#xff0c;實現對數據處理的快速響應。 易擴展&#xff1a;Shared-Nothing開放架構…

電梯物聯網之梯控相機方案-防止電瓶車進電梯

梯控現狀 隨著電梯產品在智能化建筑的日益普及,對于電梯的智能化管理 安全性需求 的要求越來越迫切。尤其今年來隨著電瓶車的大量普及&#xff0c;發起多起樓道、轎廂電瓶車著火惡性事件&#xff0c; 造成了極大的社會 負面影響。控制電瓶車進入單元門&#xff0c;樓道以及電梯…

Vue官網“食用指南”

把Vue官網當做一個工具來用&#xff0c;有問題&#xff0c;先來官網查一查。 官網中常用的板塊 官網&#xff1a;https://cn.vuejs.org/上手后&#xff0c;最常用的模塊是【快速上手】【API】。所以務必要知道這兩個模塊在哪里&#xff0c;怎么使用。![image.png](https://img…

/proc/cpuinfo文件內容詳解

/proc/cpuinfo 文件包含了有關系統 CPU 的信息&#xff0c;每一行代表一個屬性及其對應的值。以下是一些常見的屬性及其含義&#xff1a; 1. processor&#xff1a;表示 CPU 的物理編號&#xff0c;通常從 0 開始遞增。 2. vendor_id&#xff1a;CPU 廠商的名稱&#xff0c;如…

藍橋杯 砝碼稱重 dp/dfs

題目鏈接&#xff1a; https://www.lanqiao.cn/problems/1447/learning/?subject_code1&group_code4&match_num12&match_flow1&origincup 思想&#xff1a;dfs暴力枚舉過一半的分 代碼&#xff1a; #include<bits/stdc.h> using namespace std;#def…

快速開發一個鴻蒙的頁面

文章目錄 前言常用組件快速開啟簡單的鴻蒙頁面總結 一、前言 鴻蒙要想快速上手&#xff0c;那么就需要對基礎的組件使用比較熟悉&#xff0c;這里就羅列開發中常見的基礎組件的使用。 只要是寫android的&#xff0c;對于這些組件的使用還是能很快上手的&#xff0c;只要多多…