Linux運維---shell腳本練習串燒1

腳本說明
1.腳本1:解決重裝大量的庫文件
2.腳本2:選擇並切換到想要切換的工作目錄

腳本1說明:

某位員工的centos7主機系統出現如下問題:

執行ldconfig命令時報如下錯誤:庫文件是空的,長度爲0,需要重裝這些庫文件。               
ldconfig: File /lib/libstdc++.so.6 is empty, not checked.
ldconfig: File /lib/libstdc++.so.6.0.19 is empty, not checked.
ldconfig: File /lib/libaudit.so.1 is empty, not checked.
ldconfig: File /lib/libaudit.so.1.0.0 is empty, not checked.
ldconfig: File /lib/libauparse.so.0 is empty, not checked.
ldconfig: File /lib/libauparse.so.0.0.0 is empty, not checked.
ldconfig: File /lib/libdw-0.172.so is empty, not checked.
ldconfig: File /lib/liblz4.so.1 is empty, not checked.
ldconfig: File /lib/libelf-0.172.so is empty, not checked.
ldconfig: File /lib/libasm-0.172.so is empty, not checked.
ldconfig: File /lib/liblz4.so.1.7.5 is empty, not checked.
ldconfig: File /lib64/libXfont.so.1 is empty, not checked.
ldconfig: File /lib64/libXfont.so.1.4.1 is empty, not checked.
ldconfig: File /lib64/libical.so.1 is empty, not checked.
ldconfig: File /lib64/libical.so.1.0.1 is empty, not checked.
ldconfig: File /lib64/libicalss.so.1 is empty, not checked.
ldconfig: File /lib64/libicalss.so.1.0.1 is empty, not checked.
ldconfig: File /lib64/libicalvcal.so.1 is empty, not checked.
ldconfig: File /lib64/libicalvcal.so.1.0.1 is empty, not checked.
ldconfig: File /lib64/libminizip.so.1 is empty, not checked.
ldconfig: File /lib64/libminizip.so.1.0.0 is empty, not checked.
ldconfig: File /lib64/libgit2-glib-1.0.so.0 is empty, not checked.
ldconfig: File /lib64/libgit2-glib-1.0.so.0.2600.4 is empty, not checked.
ldconfig: File /lib64/libopenconnect.so.5.4.0 is empty, not checked.
ldconfig: File /lib64/libnghttp2.so.14.16.1 is empty, not checked.
.............省略

如上所示:需要重裝這些庫文件,不過並不是每行信息顯示的都是庫文件,有的行是軟鏈接文件,因爲鏈接的庫文件爲空,所以軟鏈接文件也爲空。

腳本1思路
1.首先需要截取出庫文件的完整路徑和名稱,比如(/lib64/libical.so)這樣。
2.通過rpm -qf 庫文件名能夠查出該庫文件屬於哪個軟件包,重裝該軟件包即可。
3.需要針對軟鏈接文件做判斷,如果是鏈接文件,就不執行重裝命令。
4.使用循環去遍歷庫文件列表,這裏使用的是while循環。

腳本1內容

#/bin/bash
LDCONFIG=`ldconfig 2>&1|sort|awk '{print $3}'`        #截取出庫文件名稱,因爲ldconfig命令輸出的是錯誤輸出消息,所以這裏用2>&1將錯誤輸出重定向到標準輸出,管道後的命令才能接受信息。

echo "$LDCONFIG" |           #這裏用管道這種方式讓while循環處理庫文件列表,注意加上雙引號
while read line                      #while read line 經典組合
 do
   if [ `ls -l $line | grep -c '^l'` -ne 0 ]         #判斷文件是否是鏈接文件,grep -c 統計匹配串出現的次數,如果是鏈接文件,grep -c '^l' 就是1,1不等於0成立,執行continue語句,跳出當前循環
     then
         continue
   else
         PACKAGE=`rpm -qf $line`             #如果是庫文件,那麼查詢該庫文件屬於哪個包
         if [ `echo "$PACKAGE" | wc -l` -eq 1 ]   #判斷庫文件屬於的包是否只有一個,如果只有一個,就重裝該包
           then
                echo "prepare reinstall $PACKAGE"
                yes | yum reinstall $PACKAGE        #yes命令如果不跟參數,就會一直輸出y,爲什麼不使用yum -y install? 因爲無聊
                [ $? -eq 0 ] && echo "$PACKAGE reinstall succes" || echo "$PACKAGE reinstall failed"  
           else  
                echo 'I don not know need reinstall which PACKAGE'               
         fi
   fi
 done

腳本1小結
該腳本沒有針對日誌信息,以及安裝出錯等其他信息的記錄,簡單的滿足重裝大量庫文件,不能重裝的庫文件單獨解決即可。

腳本2說明

工作中經常頻繁的切換到某些目錄,剛好看書看到pushd、popd、dirs等命令的介紹,就想寫個利用這些命令來切換目錄的腳本,該腳本用到的命令說明:

1.pushd命令:shell內置命令,pushd命令帶上目錄名作爲參數的使用可以將該目錄添加到目錄棧中。如果參數是+n(這裏n是一個數字),pushd將旋轉棧,從最左邊開始棧中的第n個目錄將被放到棧頂,同時切換到該目錄。..........(內容來自Unix shell範例精解第四版)

2.popd命令:shell內置命令,popd命令從棧頂刪除一個目錄並切換到那個目錄。............(內容來自Unix shell範例精解第四版)

3.dirs命令:帶-l選項的內置命令dirs,將以完全路徑名的格式顯示目錄棧中的所有目錄。...........(內容來自Unix shell範例精解第四版)

腳本2思路

1.使用select製作目錄菜單,選擇哪個目錄就切換到該目錄
2.需要用pushd將目錄加入目錄棧,用popd命令將目錄從目錄棧中彈出
3.需要用dirs命令例出目錄棧中的目錄以及目錄的編號

腳本2內容

這是寫到/etc/profile文件中的一個函數,剛開始單獨寫成腳本文件然後執行腳本,發現並沒有切換目錄,應該是執行腳本時產生了新的進程,所以在當前進程並沒有切換目錄,後面就沒有繼續測試腳本了,就將它寫成函數放到/etc/profile文件裏,內容如下:

function cdir ()       #函數名稱cdir
{
DIRS="                  #該變量存放目錄列表
/home/kevin.tao/git-server/puppet/modules/nagios/files/client/centos7
/home/kevin.tao/git-server/puppet/modules/nagios/files/server/objects
/home/kevin.tao/git-server/puppet/modules/db_backup
/home/kevin.tao/git-server/puppet/manifests
/home/kevin.tao/Desktop"
set $DIRS             #set 命令可以給位置參數重新賦值,這裏就把目錄名變成$1 $2 $3 $4 ........
while popd ; do : ; done &>/dev/null    #while循環條件是popd命令,將目錄棧清空,如果不清空,每執行一次函數,就會重複添加目錄到目錄棧中,這樣就不對了
until [ -z $1 ]          #until循環用來將目錄添加到目錄棧中,注意shift命令
do
   pushd $1 &>/dev/null
   shift
done
PUSH=`dirs -l -v|sed '$d'|sed 's/ //g'`    #PUSH變量用來存放目錄棧中的目錄列表以及目錄編號(n)
PS3="Please choose directory"           
select DIR in $PUSH                            #select菜單,選擇要切換的目錄
do
    NUM=${DIR%%/*}               #選擇了哪個目錄,這裏就會將該目錄在棧中的目錄編號截取出來
    pushd +$NUM &>/dev/null       #pushd命令加上目錄編號就能切換到該目錄
    break
done 
}

export -f cdir

腳本2執行

[kevin.tao@cws76 ~]$ cdir 
1) 0/home/kevin.tao/Desktop
2) 1/home/kevin.tao/git-server/puppet/manifests
3) 2/home/kevin.tao/git-server/puppet/modules/db_backup
4) 3/home/kevin.tao/git-server/puppet/modules/nagios/files/server/objects
5) 4/home/kevin.tao/git-server/puppet/modules/nagios/files/client/centos7
Please choose directory2
[kevin.tao@cws76 manifests]$     #成功切換到選擇的目錄

腳本2小結

寫腳本的時候會遇到很多問題,需要慢慢去修補漏洞。剛開始以爲不需要用到popd命令,後面發現目錄棧中重複目錄太多,只能一個個目錄彈出。如果使用cd命令估計就會容易得多,但是沒有試過,想多嘗試一些不同的方法、不同的技巧,這樣更能提升shell編程的能力。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章