1. 程式人生 > 其它 >Shell 分發指令碼

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 建立多級目錄,如果目錄存在也不會報錯