Shell 分發指令碼
Shell分發指令碼
原理
在叢集中,我們經常會有此需求:迴圈複製檔案到所有節點的相同目錄下,不用一個節點一個節點單獨使用命令,提高效率。
核心思想
rsync上進行封裝
rsync命令分析
特點
rsync遠端同步工具
rsync主要用於備份和映象。具有速度快、避免複製相同的內容和支援符號連結的優點。
rsync和scp區別
rsync:速度更快,只更新差異檔案,第一次同步 = scp。
scp:複製所有的檔案。
基本語法
rsync -av(選擇引數) 要拷貝的檔案路徑 目的使用者@主機:目的路徑
-a 歸檔拷貝
-v 顯示覆制過程
-r 對子目錄以遞迴模式處理
實現
需求
迴圈複製檔案(這裡只針對檔案)到所有節點的相同目錄下
命令:xsync 要同步的檔名稱
這裡就需要在指令碼中新增叢集中節點,還有一種做法是可以通過在命令中傳需要該檔案的節點來傳檔案,還可以通過傳參來確定是複製檔案還是複製目錄等。
這裡我們就做最簡單的實現,在指令碼中新增叢集中節點。在後續的使用中如果有其他需求,再在此基礎上做改進。
使用rsync 實現需求
rsync -av /opt/module/ ranan@hadoop103:/opt/module
所以我們需要獲得當前的路徑,當前的使用者名稱及需要傳遞的主機名
環境變數
期望指令碼在任何路徑都能使用
指令碼放在聲明瞭全域性環境變數的路徑下
可以通過 echo $PATH 檢視聲明瞭全域性環境變數的路徑
指令碼實現
#指定bash解析器 #!/bin/bash #1. $# 獲得引數個數 # 判斷引數是否小於1,-lt (less than)小於,至少需要傳送的檔案 if [ $# -lt 1 ] then echo Not Enough Arguement! exit; fi #2. 遍歷叢集所有機器 # 對102,103,104都進行分發 for host in hadoop102 hadoop103 hadoop104 do # $host使用host變數 echo ==================== $host ==================== #3. $@代表命令列中所有的引數,也就是需要傳送的檔案,可以是多個 for file in $@ do #4. 判斷檔案是否存在 -e 檔案存在(existence) if [ -e $file ] then #5. 獲取父目錄,常用命令 # dirname 獲取指定路徑所在的目錄 ,如 dirname /home/xu 結果為 /home。 # $返回該命令的結果 # pwd -P:如果目錄是連結時, 顯示出實際路徑,而非使用連線(link)路徑。 # $(command) 等價於 `command` shell掃描一遍命令列,發現了$(command)結構,便將$(command)中的command執行一次,得到其標準輸出, pdir=$(cd -P $(dirname $file); pwd) #6. 獲取當前檔案的名稱 fname=$(basename $file) # 先建立目錄,防止傳檔案時,路徑不存在 #ssh xxx.xxx.xxx.xxx "命令",遠端執行命令 #mkdir -p遞迴建立目錄,即使上級目錄不存在,會按目錄層級自動建立目錄 # -p 目錄已存在時不會報錯 ssh $host "mkdir -p $pdir" rsync -av $pdir/$fname $host:$pdir # 如果不存在 else echo $file does not exists! fi done done
知識點
獲得當前路徑的目錄dirname
pdir=$(cd -P $(dirname $file); pwd)
$file 獲取當前路徑所在的目錄 ,如 dirname /home/xu 結果為 /home。
$ 返回該命令的結果
pwd -P:如果目錄是連結時,顯示出實際路徑,而非使用連線(link)路徑。
cd -P:如果目錄是連結時,切換到實際路徑的目錄。
獲得當前路徑的檔名basename
basename命令格式:
basename [pathname] [suffix]
basename [string] [suffix]
suffix為字尾,如果suffix被指定了,basename會將pathname或string中的suffix去掉。
示例:
$ basename /tmp/test/file.txt
file.txt
$ basename /tmp/test/file.txt .txt
file
shell遠端執行命令
ssh [email protected] "pwd; cat hello.txt" //遠端執行兩條命令,使用者名稱ranan
ssh xxx.xxx.xxx.xxx "命令"
mkdir目錄存在不報錯
mkdir 目錄,目錄存在 mkdir的命令就會報錯。
mkdir -p 建立多級目錄,如果目錄存在也不會報錯。