Bash腳本編程(原創)


BashUnix shell的一種,在1987年由布萊恩·福克斯為了GNU計劃而編寫。1989年釋出第一個正式版本,原先是計劃用在GNU作業系統上,但能運行於大多數類Unix系統的操作系統之上,包括LinuxMac OS X v10.4都將它作為預設shell。它也被移植到Microsoft Windows上的CygwinMinGW,或是可以在MS-DOS上使用的DJGPP專案。在Novell NetWareAndriod在上也有移植。1990年後,Chet Ramey成爲了主要的維護者。為Bourne shell的後繼相容版本與開放原始碼版本,它的名稱來自Bourne shellsh)的一個雙關語(Bourne again / born again):Bourne-Again SHell

Shell中文意思叫做,在計算機中它是和用戶直接交互的一個界面,而我們通常用到的是文本界面的shell

硬體、核心與使用者的相關性圖示

bash啓動的時候會運行各種不同的腳本。當bash作爲一個登錄的交互shell被調用,或者作爲非交互shell但帶有--login參數被調用時,它首先讀入並執行文件/etc/profile。然後它會依次尋找~/.bash_profile~/.bash_login,和~/.profile,讀入並執行第一個存在且可讀的文件。--noprofile參數可以阻止bash啓動時的這種行爲。當一個登錄shell退出時,bash讀取並執行~/.bash_logout文件,如果此文件存在。當一個交互的非登錄shell啓動後,bash讀取並執行~/.bashrc文件。這個行爲可以用--norc參數阻止。--rcfile file參數強制bash讀取並執行指定的file而不是默認的~/.bashrc。如果用sh來調用bashbash在啓動後進入posix模式,它會儘可能模仿sh歷史版本的啓動行爲,以便遵守POSIX標準。用sh名字調用的非交互shell不會去讀取其他啓動腳本,--rcfile參數無效。當bashPOSIX模式啓動時(例如帶有--posix參數)它使用POSIX標準來讀取啓動文件。在此模式下,交互shells擴展變量ENV,從以此爲文件名的文件中讀取命令並執行。bash會探測自己是不是被遠程shell守護程序運行(通常是rshd)。如果是,它會讀取並執行~/.bashrc中的命令。但是rshd一般不會用rc相關參數調用shell,也不會允許指定這些參數。

以上是我們對bash的簡單介紹,接下來我們就說一下關於bash腳本編寫的一些內容,在http://linuxlover.blog.51cto.com/2470728/1631593此篇博客中我提供過幾個簡單的例子大家可以去看一下。

1bash中的變量

變量命名規則:

         1.只能包含字母、數字和下劃線,並且不能以數字開頭

         2.不應與系統中已有的變量重名

         3.最好做到見名知意

1.1、變量:是指在內存中抽出一塊空間,然後把這塊空間命名,其內部可以放東西,類似一個有名字的容器。

環境變量:即全局變量,變量的作用域爲本shell及其子shell

本地變量:也有人叫全局變量相對局部變量而言,作用範圍爲整個shell自身。

局部變量:只用關鍵字local定義,作用範圍爲某段代碼,一般都是在函數體中使用,函數調用結束變量撤銷。

位置變量:即代表腳本各參數的位置,$0~$9,一共十個如果多餘十個則需要用其他的方法,其中$0代表腳本本身。

特殊變量:具有特殊功能的變量

$# 表示傳遞到腳本的參數列表

$* 以一個字符串顯示所有向腳本傳遞的參數,跟位置變量不同的是這裏參數可超過9個。

$$ 表示當前運行腳本的進程ID

$! 表示後臺運行的一個進程的ID

$@ $#相同,但是使用時加引號,並在引號中返回每一個參數

$- 顯示shell使用的當前選項,set命令相同

$? 顯示最後命令運行的推出狀態,0表示沒有錯誤,其他任何值表示有錯誤

數值型:整型、浮點型

字符型:字符、字符串

布爾型:真、假

1.2、與變量相關的一些命令

declare 創建或顯示變量

        參數-f 只顯示函數名

        參數-r 創建只讀變量(typeset也可以)

        參數-x 創建轉出變量

        參數-i 創建整數變量

        如果參數中使用+來代替-,表示選項的含義相反。

export 創建環境變量

        參數– 表明選項結束,所有後面的參數都是實參

        參數-f 表示在”變量-值”對照中的變量是一個函數名

        參數-n 表示把全局變量轉換成局部變量(也就是本地變量)

        參數-p 顯示全局變量列表

readonly 創建或顯示只讀變量

        參數– 表示選項結束

        參數-f 創建只讀變量

set 設置或者重設各種shell

shift [n] 用來移動或調整位置變量,使$4賦給$3(也就是全都向前面移動一次),這個裏面的n表示移動幾位,默認是移動一位。

typeset 這個就跟declare相同了

unset 清除變量的定義

        參數– 表示選項結束

        參數-f 刪除只讀變量,但是不能sehll環境中制定的變量和函數。

read 用於從終端或者文件中讀取輸入,它讀取整行輸入,而末尾的換行符被翻譯成 null(空字符串)。如果沒有指定名稱,讀取的行就被賦值到特定的變量 REPLY 中。同時,read 命令還可以用來使程序暫時停下來等待用戶輸入回車。

        -a array 將單詞清單放入 array 數組中

        first last 讀取輸入到第一個空格或回車,將輸入的第一個單詞放入 first 中,而其他的則放在 last

        -p prompt 打印提示,等待輸入,並將輸入存入 REPLY

        -r line 允許輸入中包含反斜槓 ”\ ”

        -t timaout:指定等待接受參數的時間

        -n:表示不換行

1.3、變量替換

2bash中的運算

2.1、算數運算:需要變量爲數值型,但默認直接進行變量賦值時都是字符型,所以需要顯示的定義可以使用declarelet命令。但bash是解釋型語言(還有編譯型語言),所以變量的定義非常寬泛,在定義時可以不不指明變量類型,使用時在指明就可以了。

算術運算符:

+:加

-:減

*:乘

/:整

%:取模

**:冪

運算方法:

let c=$a+$b

c=$[$a+$b]

c=$(($a+$b))

c=$(expr $a + $b) | c=`expr $a + $b`

2.2、邏輯運算:即與、或、非以及條件測試運算。

命令間的邏輯關係:

         邏輯與:&& 有一個爲假,結果爲假

                   第一個條件爲假時,第二個條件不再判斷;

                   第一個條件爲真時,第二個條件必須判斷;

         邏輯或:|| 有一個爲真,結果爲真

                   第一個條件爲真時,第二個條件不再判斷;

                   第一個條件爲假時,第二個條件必須判斷;

         邏輯非:!

條件測試類型:

         整數測試

         字符測試

         文件測試

條件測試的表達式:

         [ expression ]  命令測試法  表達式

         [[ expreession ]]  關鍵字測試法

         test expression

整數比較(雙目操作)

         -eq:測試兩個整數是否相等,如:[ $a -eq $b ] 測試ab兩個變量中的數是否一致,一致狀態返回值爲0 echo $?

         -ne:測試兩個整數是否不等,不等爲真,相等爲假

         -gt:測試一個數是否大於另一個數,大於爲真,否則爲假

         -lt:測試一個數是否小於另一個數,小於爲真,否則爲假

         -ge:大於或等於

         -le:小於或等於

文件測試:

-a file exists.

-b file exists and is a block special file.

-c file exists and is a character special file.

-d file exists and is a directory.

-e file exists (just the same as -a).

-f file exists and is a regular file.

-g file exists and has its setgid(2) bit set.

-G file exists and has the same group ID as this process.

-k file exists and has its sticky bit set.

-L file exists and is a symbolic link.

-n string length is not zero.

-o Named option is set on.

-O file exists and is owned by the user ID of this process.

-p file exists and is a first in, first out (FIFO) special file or named pipe.

-r file exists and is readable by the current process.

-s file exists and has a size greater than zero.

-S file exists and is a socket.

-t file descriptor number fildes is open and associated with a terminal device.

-u file exists and has its setuid(2) bit set.

-w file exists and is writable by the current process.

-x file exists and is executable by the current process.

-z string length is zero.

字符測試:字符串比較

雙目:

>: 大於則爲真

<: 小於則爲真

>=:大於等於則爲真

<=:小於等於則爲真

==:等於則爲真

!=:不等於則爲真

單目:

-n String: 是否不空,不空則爲真,空則爲假

-z String: 是否爲空,空則爲真,不空則假

3、條件測試語句和循環語句

3.1if語句

格式:

1 一般

if command

then

commands

fi

2test 模式

if test expression

then

commands

fi

if [ string/numeric expression ]

then

commands

fi

if [[ string exprssion ]]

then

commands

fi

3let 模式

if (( numeric expression ))

then

commands

fi

嵌套 if 命令:

格式:

if command

then

commands

else

commands

fi

if/elif/else 命令:

格式:

if command

then

command(s)

elif command

then

command(s)

…………

else

command(s)

fi

3.2case 語句

case 值中允許出現 shell 通配符和豎線(|)作爲 OR 操作符。*) 的作用相當於 else語句。

格式:

case variable in

value1)

command(s)

;;

value2)

command(s)

;;

………………

*)

command(s)

;;

esac

4、循環語句

4.1for循環

格式:

for variable in word_list

do

command(s)

done

寫成一行:

for var in item1 item2 ... itemN; do command1; command2… done;

C風格的形式:

for (( EXP1; EXP2; EXP3 ))

do

    command1

    command2

    command3

done

4.2while循環

格式:

while condition

do

    command

done

特殊用法:遍歷文件的每一行

while read VAR_NAME; do

    command(s)

done < /path/to/somefile

4.3until循環

until 的用法跟 while 的類似,只是在 until 後面的語句爲假的時候執行循環體。

格式:

until command

do

commands

done

4.4、無限循環

while :

do

    command

done

或者

while true

do

    command

done

或者

for (( ; ; ))

或者

until false; do

      command

done

4.5、循環中的控制語句

1break 命令:

用來從循環中強行退出,但不退出程序。Break 後加一個數字可用來指定 break 強行退出的循環的層數。其中,最外面的循環數是 1,依次往裏是 23……

格式:

break [n]

2continue 命令:

如果某些條件爲真,continue 就控制跳轉到循環的頂部,所以 continue 後面的語句將被忽略。Continue 後加一個數字可控制跳轉到任何層的循環頂部重新開始執行。其中,最內的循環、號是 1,往外依次是 23……

格式:

continue [n]

3shift 命令:

用來把參量列表位移指定次數,沒有參數的 shift 把參量列表向左移動一位。一旦位移發生,被位移出列表的參數就被永遠刪除了。通常在 while 循環中,shift 用來讀取列表中的參量。

格式:

shift [n]

5、函數:函數本身就是一個命令或一組命令的名字。函數可以使程序模塊化,提高效率,可以就在當前的 shell 環境中執行,即在執行像 ls 等可執行程序時不產生自進程。

使用函數的規則:

1shell 總是先執行別名,然後是函數、內建命令,最後才執行可執行程序。

2、函數使用前必須先定義。

3、函數在當前環境下執行,它和調用它的腳本分享變量,並通過位置參量傳遞參數。通過 local 函數可以在函數內部建立本地變量。

4、如果在函數中使用 exit,則可以退出整個腳本,而退出函數則只是返回到調用函數的地方。

5return 命令返回函數中最後一個命令的退出狀態值或者是給定的參數值。

6、使用 export -f 可以將函數輸出到子 shell

7、使用 declare -f 可顯示定義的函數清單,而 declare -F 則只顯示函數的名字。

8、函數內部的陷阱是全局的,它們可以被腳本和腳本激活的函數共享。如果一個陷阱被定義爲函數,它就可以被腳本共享,但可能產生意想不到的效果。

9、如果函數保存在其他文件中,必須通過 source 或者 dot 命令把它們裝入當前腳本。

10、函數可以遞歸,且其遞歸次數沒有限制。

5.1、函數定義

1)構建函數

格式:

function function_name { comand(s); command(s); }

2)復位函數:使用 unset 命令將函數從內存中刪除。

格式:

unset -f function_name

3)輸出函數:輸出到給子 shell

格式:

export -f function_name

5.2、函數參數和返回值

1)內建 local 函數:

local 創建的變量只在函數內部使用,退出函數變量即實效。

2)參數:

通過位置參量可以向函數傳遞參數,該參數不會影響函數外使用的任何位置參量。

3)內建 return 函數:

return 用來退出函數並返回到調用函數的地方。如果沒有給 return 指定參數,返回的函數值就是最後一行的退出狀態值。Return 返回的值只能是 0~256 之間的整數,且該值保存在“ ?”中,同時可以使用命令替換來捕捉函數的輸出,即把整個函數放在括號內,前面加$(即:$(function_name)),或者通過引號把輸出賦值給一個變量。

5.3source(或者 dot)命令

函數通常被定義到.profile 中,當需要使用函數時,可以使用 source 或者 dot 加文件名來激活這些在文件中定義的函數。此命令也經常用在bash腳本的開頭出以讀取配置文件,獲取其中的變量值。

7、陷阱信號

當程序運行時,按下 Control-C 或者 Control-/後程序就立刻終止,但很多時候當不希望信號到達時程序就立刻停止運行,而是希望忽略這個信號繼續運行下去或者在程序退出前做些清除操作。這些可以通過 trap 命令來控制程序在收到信號以後的行爲。信號是由一個進程發送給另外一個進程的,或者在特定的鍵按下以後由操作系統發送給進程的,又或者在異常情況下發生時,由數字組成的非同步的消息。Trap 命令告訴 shell 根據收到的信號而以不同的方式終止當前的進程。如果 trap 後面跟着一個用引號引用的命令,則在接收到指定的信號數字時就執行這個命令。Shell 共讀取兩次命令字符串,一次是在設置 trap 時,一次是在信號到達時。如果命令字符串被雙引號引用,在第一次 trap 設置時就執行變量和命令替換。如果是用單引號引用,那麼等到信號到達 trap 開始執行時,才運行變量和命令替換。

格式:

trap 'command;command' signal_number

trap 'command;command' signal_name

eg:

trap 'rm tmp*;exit 1' 0 1 2 15

trap 'rm tmp*;exit 1' EXIT HUP INT TERM

注:當 1(掛起)、2(中斷)或者 15(軟件終止)任何一個信息到達時就執行 rm exit

 

Bash 允許在信號上使用象徵性名稱,例如沒有前綴(SIG)或者用數字作爲信號的名稱。一個叫做 EXIT 的或者數字 0 的僞信號,將在 shell 退出時,導致一個陷阱的執行。

1)信號復位:

trap 後面加一個信號或者數字,可把信號復位爲默認動作。一旦調用了函數,函數設置的陷阱可以被調用這個函數的 shell 識別。同時,在函數外設置的陷阱也可被函數識別。

Eg trap 2 或者 trap INT,表示恢復當 Control-C 按下就殺死當前進程的默認動作。

trap trap 2 2 表示用戶必須按兩次 Control-C 才能終止程序,其中第一個陷阱捕捉信號,第二個復位信號默認動作爲殺死進程。

2)忽略信號:

如果 trap 後面跟一對空括號,列表中的信號將被進程忽略。

Eg trap " " 1 2 or trap " " HUP INT

注:信號 12 將被 shell 進程忽略。

3)陷阱列表:

通過 trap 命令可顯示陷阱列表和分配給陷阱的命令清單。

Eg

[root@localhost root]# trap 'echo hehe!;exit 1' 2

[root@localhost root]# trap

trap -- 'echo hehe!;exit 1' SIGINT

4)函數中的陷阱:

如果使用陷阱處理函數中的信號,一旦函數被激活,它將影響整個腳本,即陷阱對於腳本來說是全局的。

6、數組:

         數組:變量陣列,通過同一個名字進行存取操作;

                   連續的多個獨立的內存空間(元素),每個內存空間相當於一個變量;

                  bash的數組支持稀疏格式;

                   數組元素:數組名[索引]

                            索引:從0開始編號

         聲明數組:

                   declare -a Array_Name

關聯數組:

                   bash4.0版本起支持關聯數組:數組索引可爲自定的字符串;

declare -A ARRAY_NAME

6.1、數組元素賦值:

                   (1) 一次只賦值一個元素

                            a_name[index]=value

                            weekday[0]="Sunday"

                            weekday[1]="Monday"

                   (2) 一次賦值全部元素

                            weekday=("Sunday" "Monday" "Tuesday")

                   (3) 指定索引進行賦值

                            weekdays=([0]="Sunday" [3]="Thu" [6]="Sat")

                   (4) read -a a_name

         引用數組元素:${array_name[index]}

         獲取數組長度:${#array[*]}, ${#array[@]}

                   即數組中元素的個數;

6.2、數組切片:從數組中挑選指定的某個或某些元素:

                            ${array[@]:offset:number}

                                     offset: 偏移的元素的個數;

                                     number:要取出的元素的個數;

                            ${array[@]:offset}

                                     取出偏移量之後剩餘所有的元素;

                            ${array[@]}

                   從數組中刪除元素:

                            unset array[index]

7bash的字符串處理:

7.1、字符串切片:${var:offset:length}

         取出字符串的最後幾個字符:${var: -length}

                   注意:-length之前有空白字符;

7.2、基於模式取子串:

         ${var#*word}:自左而右,查找var變量中存儲的字符串中第一次出現的由word所指明的字符,刪除此字符及其左側的所有內容;

         ${var##*word}:自左而右,查找var變量中存儲的字符串中最後一次出現的由word所指明的字符,刪除此字符及其左側的所有內容;

         ${var%word*}:自右而左,查找var變量中存儲的字符串中第一次出現的由word所指明的字符,刪除此字符及其右側的所有內容;

         ${var%%word*}:自右而左,查找var變量中存儲的字符串中最後一次出現的由word所指明的字符,刪除此字符及其右側的所有內容;

示例:

         url="http://www.magedu.com:80"

         取端口:echo ${url##*:}

         取協議:echo ${url%%:*}

7.3、查找替換:

         ${var/pattern/replacement}:查找var變量存儲的字符中第一次由pattern匹配到的內容,並替換爲replacement

         ${var//pattern/replacement}:查找var變量存儲的字符中所有能夠由pattern匹配到的內容,並替換爲replacement

         ${var/#pattern/replacement}:查找var變量存儲的字符中最開始處能夠由pattern匹配到的內容,並替換爲replacement

         ${var/%pattern/replacement}:查找var變量存儲的字符中最後位置能夠由pattern匹配到的內容,並替換爲replacement

7.4、查找刪除:

         ${var/pattern}:查找var變量存儲的字符中第一次由pattern匹配到的內容,並刪除;

         ${var//pattern}:查找var變量存儲的字符中所有能夠由pattern匹配到的內容,並刪除;

         ${var/#pattern}:查找var變量存儲的字符中最開始處能夠由pattern匹配到的內容,並刪除;

         ${var/%pattern}:查找var變量存儲的字符中最後位置能夠由pattern匹配到的內容,並刪除;

7.5、字符串大小寫轉換:

         ${var^^}:把var變量中的所有小寫字母,統統替換爲大寫;

         ${var,,}:把var變量中的所有大寫字母,統統替換爲小寫;

8shell運行調試

腳本的調試可用 bash set 命令來實現。Bash set 跟蹤調試時,執行腳本中的每行都會在前面加一個(+)號。

 

9、其它補充

9.1、特殊含義字符彙總

9.2mktemp命令:

mktemp [OPTIONS] filename.XXX

-d: 創建臨時目錄

--tmpdir=/path/to/somewhere :指定臨時文件所在的目錄

mktemp /tmp/tmp.XXX                    #XXX生成相同數量隨機字符

mktemp --tmpdir=/tmp tmp.XXX       #指定目錄創建臨時文件

mktemp --tmpdir=/tmp -d tmp.XXX    #指定目錄創建臨時目錄

9.2install命令:

install [OPTIONS] SOURCE DEST

install [OPTIONS] SOURCE... DIR

install [OPTIONS] -d DIR ...

增強型的複製命令:

-o OWNER

-g GROUP

-m MODE

-d : 創建目錄

install /etc/fstab /tmp                 #複製文件到指定目錄

install --mode=644 /etc/issue /tmp/     #複製時指定權限

install --owner=czc /etc/issue /tmp #複製時指定屬主

install --group=czc /etc/issue /tmp #複製時指定屬組

install -d /tmp/hello                 #創建目錄

10、一些實例

練習:寫一個腳本

從鍵盤讓用戶輸入幾個文件,腳本能夠將此幾個文件歸檔壓縮成一個文件;

#!/bin/bash

#

read -p "Please input tarname:" TAR

read -p "Please input filename:" FILE

read -p "Compress [gzip|bzip2|xz]:" COM

case $COM in

gzip)

         tar -zcf ${TAR}.tar.gz $FILE ;;

bzip2)

         tar -jcf ${TAR}.tar.bz2 $FILE ;;

xz)

         tar -cf ${TAR}.tar $FILE

         xz ${TAR}.tar ;;

*)

         echo "Unkown."

         exit 8 ;;

esac

 

寫一個腳本:

1) 顯示一個菜單給用戶:

d|D) show disk usages.

m|M) show memory usages.

s|S) show swap usages.

*) quit.

2) 當用戶給定選項後顯示相應的內容;

  

擴展:

         當用戶選擇完成,顯示相應信息後,不退出;而讓用戶再一次選擇,再次顯示相應內容;除了用戶使用quit

#!/bin/bash

#

while ! who | grep "hadoop" &> /dev/null;do

         sleep 5

         echo "The user hadoop does not loggin."

done

echo "Hadoop loggin."

[root@localhost ~]#

[root@localhost ~]# cat slectshow.sh

#!/bin/bash

#

cat << EOF

d|D) show disk usages.

m|M) show memory usages.

s|S) show swap usages.

q|quit) exit.

EOF

read -p "Please input your chioce:" CHO

while [ $CHO != 'quit' ];do

         case $CHO in

                   d|D)

                            df -h ;;

                   m|M)

                            free -m | grep  "Mem" ;;

                   s|S)

                            free -m | grep  "Swap" ;;

                   q|quit)

                            exit 0 ;;

                   *)

                            echo "Your chionce must be in:"

                            cat << EOF

                            d|D) show disk usages.

                            m|M) show memory usages.

                            s|S) show swap usages.

                            q|quit) exit.

EOF

                   esac

                   read -p "Please input your chioce:" CHO

done

 

寫一個腳本(前提:請爲虛擬機新增一塊硬盤,假設它爲/dev/sdb),爲指定的硬盤創建分區:

1、列出當前系統上所有的磁盤,讓用戶選擇,如果選擇quit則退出腳本;如果用戶選擇錯誤,就讓用戶重新選擇;

2、當用戶選擇後,提醒用戶確認接下來的操作可能會損壞數據,並請用戶確認;如果用戶選擇y就繼續,n就退出;否則,讓用戶重新選擇;

3、抹除那塊硬盤上的所有分區(提示,抹除所有分區後執行sync命令,並讓腳本睡眠3秒鐘後再分區);併爲其創建三個主分區,第一個爲20M,第二個爲512M, 第三個爲128M,且第三個爲swap分區類型;(提示:將分區命令通過echo傳送給fdisk即可實現)

  1 #!/bin/bash

  2 #

  3 fdisk -l 2> /dev/null | grep "^Disk /dev/[sh]d[a-z]"

  4 read -p "Please input your choice:" DEV

  5 until fdisk -l 2> /dev/null | grep "^Disk /dev/[sh]d[a-z]" | grep "^Disk $DEV" &> /    dev/null;do

  6         if [ $DEV == 'quit' ];then

  7                 echo "Quiting..."

  8                 exit 8

  9         fi

 10         read -p "Please input your choice agin:" DEV

 11 done

 12 read -p "Next choice maybe delete all the data in $DEV,are you sure?(y|n)" CHO

 13 until [ $CHO == 'y' -o $CHO == 'n' ];do

 14         read -p "Please choice agin.Next choice maybe delete all the data in $DEV,a    re you sure?(y|n)" CHO

 15 done

 16 if [ $CHO == "n" ];then

 17         echo "Quiting..."

 18         exit 9

 19 else

 20         for i in ` mount | grep "$DEV" | awk '{print $1}'`;do

 21                 fuser -mk $i

 22                 umount $i

 23                 echo "$i unmount ok."

 24         done

 25         dd if=/dev/zero of=$DEV bs=512 count=1 &> /dev/null;

 26         sync

 27         sleep 3

 28         echo 'n

 29         p

 30         1

 31

 32         +5G

 33         n

 34         p

 35         2

 36

 37         +5G

 38         n

 39         p

 40         3

 41

 42         +5G

 43         t      

 44         3      

 45         82

 46         w

 47         ' | fdisk $DEV

 48         partprobe $DEV

 49         sync

 50         sleep 2

 51         mke2fs -j ${DEV}1

 52         mke2fs -j ${DEV}2

 53         mkswap ${DEV}3

 54 fi

 

寫一個腳本,完成以下功能:

說明:此腳本能於同一個repo文件中創建多個Yum源的指向;

1、接受一個文件名做爲參數,此文件存放至/etc/yum.repos.d目錄中,且文件名以.repo爲後綴;要求,此文件不能事先存,否則,報錯;

2、在腳本中,提醒用戶輸入repo id;如果爲quit,則退出腳本;否則,繼續完成下面的步驟;

3repo name以及baseurl的路徑,而後以repo文件的格式將其保存至指定的文件中;

4enabled默認爲1,而gpgcheck默認設定爲0

5、此腳本會循環執行多次,除非用戶爲repo id指定爲quit

  1 #!/bin/bash

  2 #

  1 if [ -e /etc/yum.repos.d/$1.repo ] || [  -z $1 ];then

  2         echo "$1 exist or error."

  3         exit 9

  4 fi

  5 while [ -n $1 ];do

  6 read -p "Please input repo_id:" RID

  7 if [ $RID == quit ];then

  8         echo "Quiting...."

  9         exit 0

 10 else

 11         touch /etc/yum.repos.d/$1.repo

 12         read -p "Please input name:" NAM

 13         read -p "Please input baseurl:" BSU

 14         read -p "please input enabled:" ENB

 15                 if [ -z $ENB ];then

 16                         ENB=1

 17                 fi

 18         read -p "Please input gpgcheck:" GPG

 19                 if [ -z $GPG ];then

 20                         GPG=0

 21                 fi

 22 fi

 23 echo "[$1]

 24 name=$NAM

 25 baseurl=$BSU

 26 enabled=$ENB

 27 gpgcheck=$GPG" >> /etc/yum.repos.d/$1.repo

 28 done

 

寫一個腳本,完成如下功能:

說明:此腳本能夠爲指定網卡創建別名,則指定地址;使用格式如:mkethalias.sh -v|--verbose -i ethX

1-i選項用於指定網卡;指定完成後,要判斷其是否存在,如果不存在,就退出;

2、如果用戶指定的網卡存在,則讓用戶爲其指定一個別名,此別名可以爲空;如果不空,請確保其事先不存在,否則,要報錯,並讓用戶重新輸入;

3、在用戶輸入了一個正確的別名後,請用戶輸入地址和掩碼;並將其配置在指定的別名上;

4、如果用戶使用了-v選項,則在配置完成後,顯示其配置結果信息;否則,將不顯示;

 

  1 #!/bin/bash

  2 #

  3 V=0

  4 until [ $# == 1 ];do

  5 case $1 in

  6         -i)

  7                 if ifconfig | grep "$2" &> /dev/null ;then

  8                         read -p "Please input an alias:" ALS

  9                         while ifconfig | grep "$ALS" &> /dev/null;do

 10                                 echo "This alias is exist."

 11                                 read -p "Please input an alias agin:" ALS

 12                         done

 13                         read -p "The IP address:" IPADD

 14                         read -p "The MASK(0-32):" MASK

 15                 else

 16                         echo "This dev does not exist."

 17                         exit 8

 18                 fi

 19                 shift 1;;

 20         -v|--verbose)

 21                 V=1

 22                 shift 1;;

 23 esac

 24 done

 25 ip addr add $IPADD/$MASK dev $1 label $ALS

 26 if [ $V == 1 ];then

 27         ip addr show $1

 28 fi

 

5、創建/etc/rc.d/init.d/network服務腳本

  1 #!/bin/bash

  2 #

  3 #chconfig: 35 09 90                                     #設定啓動級別3|5,啓動優先級09,關閉優先級90

  4 #description: network service       #描述信息

  5 . /etc/rc.d/init.d/functions   #讀取functions函數文件

  6 prog=network

  7 CONF=/etc/sysconfig/network-scripts/ifcfg-eth0

  8 . $CONF

  9 NETMASK=24

 10 start() {

 11         ifconfig eth0 $IPADDR/$NETMASK up

 12         [ -z $GATEWAY ] && route add default gw $GATEWAY

 13 }

 14

 15 stop() {

 16         ifconfig eth0 down

 17 }

 18

 19 status() {

 20         ifconfig eth0

 21 }

 22

 23 usage() {

 24         echo "Usage:$prog {start|stop|restart|status}."

 25 }

 26

 27 case $1 in

 28 start)

 29         start

 30         success "Config network eth0"

 31         ;;

 32 stop)

 33         stop

 34         success "Stop network card eth0"

 35         ;;

 36 restart)

 37         stop

 38         start

 39         sucess "Restart network card eth0"

 40         ;;

 41 *)

 42         usage

 43         exit 1

 44         ;;

 45 esac

 

複製二進制程序及其依賴的庫文件的腳本:

#!/bin/bash

#

DEST=/mnt/sysroot

libcp() {

  LIBPATH=${1%/*}

  [ ! -d $DEST$LIBPATH ] && mkdir -p $DEST$LIBPATH

  [ ! -e $DEST${1} ] && cp $1 $DEST$LIBPATH && echo "copy lib $1 finished."

}

 

bincp() {

  CMDPATH=${1%/*}

  [ ! -d $DEST$CMDPATH ] && mkdir -p $DEST$CMDPATH

  [ ! -e $DEST${1} ] && cp $1 $DEST$CMDPATH

 

  for LIB in  `ldd $1 | grep -o "/.*lib\(64\)\{0,1\}/[^[:space:]]\{1,\}"`; do

    libcp $LIB

  done

}

 

read -p "Your command: " CMD

until [ $CMD == 'q' ]; do

   ! which $CMD &> /dev/null && echo "Wrong command" && read -p "Input again:" CMD && continue

  COMMAND=` which $CMD | grep -v "^alias" | grep -o "[^[:space:]]\{1,\}"`

  bincp $COMMAND

  echo "copy $COMMAND finished."

  read -p "Continue: " CMD

done

 

使用ping命令測試信號捕捉:

  1 #!/bin/bash

  2 #

  3 NET=183.170.150

  4 FILEU=`mktemp /tmp/file.XX`

  5 FILED=`mktemp /tmp/file.XXX`

  6 clear (){

  7         echo "quit..."

  8         rm -f $FILEU

  9         rm -f $FILED

 10         exit 1

 11 }

 12 trap 'clear' INT

 13 for I in {1..254};do

 14   if ping -c 1 -W 1 $NET.$I &> /dev/null;then

 15         echo "$NET.$I is up." | tee -a $FILEU #tee -a追加到文件而不是覆蓋文件

 16   else

 17         echo "$NET.$I is down." | tee -a $FILED

 18   fi

 19 done

 

練習:寫一個腳本

定義一個數組,數組元素爲/var/log目錄下所有以.log結尾的文件的名字;顯示每個文件的行數

#!/bin/bash

#

declare -a files

files=(/var/log/*.log)

for i in `seq 0 $[${#files[*]}-1]`; do

    wc -l ${files[$i]}

done

 

例:生成10個隨機數,升序排序

#!/bin/bash

for((i=0;i<10;i++))

do

    rand[$i]=$RANDOM

done

echo -e "Total=${#rand[@]}\n${rand[@]}\nBegin to sort:"

for((i=9;i>=1;i--))

do

        for((j=0;j<i;j++))

    do

    if [ ${rand[$j]} -gt ${rand[$[$j+1]]} ] ;then

        mid=${rand[$j]}

        rand[$j]=${rand[$[$j+1]]}

        rand[$[$j+1]]=$mid   

    fi

    done

done

echo ${rnd[@]}

 

打印九九乘法表:

  1 #!/bin/bash

  2 for ((i=1;i<10;i++));do

  3         for ((j=1;j<10;j++));do

  4                 if [ $i -ge $j ];then

  5                         let k=$i*$j

  6                         echo  -ne "$j*$i=$k\t"

  7                 fi

  8         done

  9         echo

 10 done

 

 

 

name=${name:-tom}    #如果name有值則將自己賦值給自己,否則將tom賦值給name


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