shell腳本編程基礎(chǔ)

技術(shù)交流QQ群:1027579432丘喻,歡迎你的加入环形!

歡迎關(guān)注我的微信公眾號:CurryCoder的程序人生

本教程使用Linux發(fā)行版Centos7.0系統(tǒng)总寻,請您注意~

1.使用多個命令

  • shell腳本的關(guān)鍵之處在于輸入多個命令并處理每個命令的結(jié)果汗销,甚至需要將一個命令的結(jié)果傳給另一個命令犹褒。shell可以讓多個命令串起來,一次執(zhí)行弛针。如果要兩個命令一起運行叠骑,可以將它們放在同一行,之間用逗號隔開削茁。
    [njust@njust tutorials]$ date;who
    2020年 03月 11日 星期三 22:39:16 CST
    njust    :0           2020-03-11 22:28 (:0)
    njust    pts/0        2020-03-11 22:35 (192.168.0.107)
    
  • 上述方法的缺點:使用上述方法可以將任意多個命令串聯(lián)在一起使用宙枷,最大命令行字符數(shù)不超過255個。對小型的腳本適用茧跋,當有很多腳本時慰丛,直接在命令行中輸入整個命令就很麻煩。

2.創(chuàng)建shell腳本文件

  • 創(chuàng)建shell腳本文件時瘾杭,必須在文件的第一行指定使用的shell是哪種類型诅病,格式為:
    #!/bin/bash
    
  • shell腳本中注釋一般以#開頭,shell腳本不會處理注釋的行。但是贤笆,shell腳本的第一行是例外蝇棉。#后的!會告訴shell用哪個shell來運行腳本,shell會根據(jù)命令在文件中出現(xiàn)的先后順序進行處理芥永。下面是創(chuàng)建腳本名為demo的文件银萍。
    #!/bin/bash
    date
    who
    
  • 存在的問題:如何讓bash shell找到你創(chuàng)建的腳本文件?shell會通過PATH環(huán)境變量來查找命令恤左。PATH環(huán)境變量被設(shè)置成只在一組目錄中查找命令贴唇。
    [njust@njust tutorials]$ echo $PATH
    /usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/home/njust/.local/bin:/home/njust/bin
    
  • 解決方法:讓shell找到腳本文件,有兩個方法:
    • 將shell腳本文件所處的目錄添加到PATH環(huán)境變量中飞袋;
    • 在命令行中使用絕對或相對的路徑來引用shell腳本文件(常用)戳气;
  • 由于你還沒有執(zhí)行文件的權(quán)限,這是由于umask變量被設(shè)置為022巧鸭,因此系統(tǒng)創(chuàng)建的文件只有讀寫權(quán)限瓶您。使用下面的命令賦予文件有可執(zhí)行權(quán)限。
    chmod u+x demo
    
  • 為了引用當前目錄下的文件纲仍,可以在shell中使用單點操作符.呀袱。正式執(zhí)行腳本demo
    ./demo
    

3.顯示消息

  • 在echo命令后加上一個字符串,該命令就會顯示出這個文本字符串郑叠。默認情況下夜赵,不需要使用引號將需要顯示的字符串包含起來。
    [njust@njust tutorials]$ echo hello world
    hello world
    
  • 當字符串中含有單引號或雙引號時乡革,可以使用雙引號或單引號(注意敘述的順序)包含該字符串寇僧。
    [njust@njust tutorials]$ echo "Let's see if this'll work"
    Let's see if this'll work
    
  • echo命令可以添加到shell腳本中任何需要顯示額外信息的地方
  • 當需要把字符串和命令輸出顯示在同一行時沸版,可以使用帶參數(shù)n的echo命令嘁傀,如下所示:
    #!/bin/bash
    
    echo -n "The time and date are: "
    date
    
    # 結(jié)果
    The time and date are: 2020年 03月 11日 星期三 23:07:03 CST
    

4.使用變量

  • 變量可以將臨時信息存儲在shell腳本中,便于和shell中其他的命令一起使用视粮。
  • 環(huán)境變量:shell維護一組環(huán)境變量细办,用來記錄特定的系統(tǒng)信息。可以使用set命令來顯示一份完整的當前環(huán)境變量列表蕾殴。
  • 在腳本中笑撞,可以在環(huán)境變量名稱前加上美元符號$從而來使用這些變量
    #!/bin/bash
    
    # print information about logger
    
    echo "User info for userid: $USER"
    echo UID: $UID
    echo HOME: $HOME
    
    # 結(jié)果
    User info for userid: njust
    UID: 1000
    HOME: /home/njust
    
  • 注意:echo命令中的環(huán)境變量會在腳本運行時替換成當前值区宇,只要腳本在引號中出現(xiàn)美元符娃殖,它就會以為你在引用一個變量,因此在表示真實美元的含義時议谷,需要在$符號前加\轉(zhuǎn)義字符炉爆。
    #!/bin/bash 
    
    echo "The cost of the item is \$5."
    
  • 此外,還可以通過${變量名}的形式引用變量,變量名兩側(cè)的{}通常用于幫助識別美元符后的變量名芬首。
  • 用戶變量:除了環(huán)境變量外赴捞,shell還允許在腳本中定義和使用自己的變量。變量名使用字母郁稍、數(shù)字或下劃線組成的字符串表示赦政,長度最長不超過20個。
  • 注意:使用等號將值賦給用戶自定義的變量耀怜,在變量恢着、等號和值之間不能出現(xiàn)空格!2破啤掰派!
    var1=23  # 等號左右不能出現(xiàn)空格!左痢!
    var2=demo
    var3=testing
    var4="hello shell"
    
  • shell腳本會自動決定變量值的數(shù)據(jù)類型靡羡。在腳本的整個生命周期內(nèi),shell腳本定義的變量會一直存在俊性,在shell腳本結(jié)束時會被刪除略步。用戶變量也可以通過$引用
    #!/bin/bash
    
    days=10
    guest="curry"
    echo "$guest checked in $days days ago"
    
    days=5
    guest="durant"
    echo "$guest cheked in $days days ago"
    
    # 結(jié)果
    curry checked in 10 days ago
    durant cheked in 5 days ago
    
  • 變量每次引用時定页,都會輸出當前賦給它的值趟薄。引用一個變量時需要使用美元符號$,引用一個變量var1給另一個變量var2進行賦值時拯勉,被賦值的變量不要使用$竟趾。對var1忘記使用$號,就會使var2的賦值行變成普通的字符串宫峦。
    #!/bin/bash
    
    var1=10
    var2=$var1  # 在賦值語句中使用var1變量的值時,必須使用$符號
    echo The resulting value is $var2
    
    # 結(jié)果 
    The resulting value is 10
    
    var2=var1;  # 錯誤的代表案例玫鸟,輸出結(jié)果是普通字符串
    echo The resulting value is $var2
    
    # 錯誤結(jié)果 
    The resulting value is var1
    
  • 命令替換:shell最有用的特性之一是從命令輸出中提取出信息导绷,并將其賦值給變量。將命令的輸出賦值給變量后屎飘,就可以在腳本中使用了妥曲。有兩種方法可以將命令輸出賦值給變量:
    • 反引號字符`
    • $()格式
  • 命令替換允許你將shell命令的輸出賦值給變量,具體如下所示:
    #!/bin/bash
    
    
    testing=`date`
    test=$(date)
    echo The date and time are: $testing
    echo The date and time are: $test
    
    # 結(jié)果
    The date and time are: 2020年 03月 12日 星期四 09:11:38 CST
    The date and time are: 2020年 03月 12日 星期四 09:11:38 CST
    
  • 實例:通過命令替換獲得當前日期并用它來生成唯一的文件名钦购。
    #!/bin/bash
    
    # copy the /usr/bin/directory listing to a log file
    
    today=$(date +%y%m%d)  # +%y%m%d格式是告訴date命令將日期顯示為兩位數(shù)的年月日數(shù)字組合
    ls /usr/bin -al > log.$today
    
    # 結(jié)果
    生成log.200312日志文件
    
  • 命令替換會創(chuàng)建一個子shell來運行對應(yīng)的命令檐盟,由該子shell所執(zhí)行命令是無法使用腳本中所創(chuàng)建的變量。在命令行中使用路徑./運行命令時押桃,也會創(chuàng)建子shell葵萎;在運行命令時不加入路徑,就不會創(chuàng)建子shell。

5.重定向輸入和輸出

  • 重定向目的:想要保存某個命令的輸出而不僅僅是讓結(jié)果輸出在屏幕上羡忘。
  • 輸出重定向:最基本的重定向是將命令的輸出發(fā)送在一個文件中谎痢。格式如下:
    具體命令 > 輸出文件名
    
  • 實例如下:
    [njust@njust tutorials]$ date > test6
    [njust@njust tutorials]$ cat test6
    2020年 03月 12日 星期四 09:40:09 CST
    
  • 如果輸出文件已經(jīng)存在,重定向操作符會用新的文件數(shù)據(jù)覆蓋已有文件卷雕。
    [njust@njust tutorials]$ who > test6
    [njust@njust tutorials]$ cat test6
    njust    :0           2020-03-11 22:28 (:0)
    njust    pts/0        2020-03-12 08:39 (192.168.0.107)
    njust    pts/1        2020-03-12 08:41 (:0)
    
  • 有時候节猿,你并不想覆蓋原始文件中的內(nèi)容,而是想將命令的輸出追加到已有文件中漫雕。這種情況下滨嘱,可以用>>來追加數(shù)據(jù)
    [njust@njust tutorials]$ date >> test6
    [njust@njust tutorials]$ cat test6
    njust    :0           2020-03-11 22:28 (:0)
    njust    pts/0        2020-03-12 08:39 (192.168.0.107)
    njust    pts/1        2020-03-12 08:41 (:0)
    2020年 03月 12日 星期四 09:43:41 CST
    
  • 輸入重定向:輸入重定向?qū)⑽募膬?nèi)容重定向到命令浸间,而不是將命令輸出重定向到文件太雨。輸入重定向的格式:
    具體命令 < 輸入文件
    
  • 具體實例:wc命令可以統(tǒng)計文件中的數(shù)據(jù),默認情況下會輸出3個值发框。
    [njust@njust tutorials]$ wc < test6
    4  21 186  # 從左到右分別表示文本的行數(shù)躺彬、文本的詞數(shù)、文本的字節(jié)數(shù)
    
  • 內(nèi)聯(lián)輸入重定向:<<無需使用文件進行重定向梅惯,只需要在命令行中指定輸入重定向的數(shù)據(jù)即可宪拥。注意:必須指定一個文本標記來劃分輸入數(shù)據(jù)的起始和結(jié)尾。任何字符串都可以作為文本標記铣减,但數(shù)據(jù)的起始和結(jié)尾文本標記必須一致她君。格式:
    具體命令 >> EOF
    data
    EOF
    
  • 在命令行中使用內(nèi)聯(lián)輸入重定向時,shell會用PS2變量中定義的次提示符來提示用戶輸入數(shù)據(jù)葫哗。
    [njust@njust tutorials]$ wc << EOF
    > test string 1  # >表示的就是次提示符
    > test string 2
    > test string 3
    > EOF
    3  9 42
    

6.管道

  • 管道的目的:一個命令的輸出作為另一個命令的輸入缔刹。
  • 管道被放在命令之間,將一個命令的輸出重定向到另一個命令中劣针⌒8洌基本格式如下:
    命令1 | 命令2
    
  • 管道串器的兩個命令不是依次執(zhí)行的,Linux系統(tǒng)實際上會同時運行這兩個命令捺典,在系統(tǒng)內(nèi)部將它們連接起來鸟廓。在第一個命令產(chǎn)生輸出的同時,輸出會被立即送個第二個命令襟己。數(shù)據(jù)傳輸不會用的任何中間文件或緩沖區(qū)引谜。
  • 可以在一條命令中使用任意多條管道∏嬖。可以持續(xù)地將命令的輸出通過管道傳給其他命令來細化操作员咽。如下例所示:
    rpm -qa | sort | more  # 先生成已安裝包的列表,再排序贮预,最后再用more顯示
    
    # 如果想更精致點贝室,可以搭配使用重定向和管道將輸出保存到文件中
    rpm -qa | sort > rpm.list
    
  • 管道最流行的用法之一就是將產(chǎn)生的大量輸出通過管道傳給more命令契讲,一般與ls命令結(jié)合使用

7.執(zhí)行數(shù)學(xué)運算

  • 在shell中有兩個途徑進行數(shù)學(xué)運算档玻。
    • expr命令
    • 使用方括號
  • expr命令允許在命令行中處理數(shù)學(xué)表達式怀泊,但特別笨拙。許多expr命令操作符在shell中另有含義误趴,當它們出現(xiàn)在expr命令中時霹琼,會得到一些詭異的結(jié)果。對那些容易被shell錯誤解釋的字符凉当,需要使用轉(zhuǎn)義字符枣申。
    [njust@njust tutorials]$ expr 5 * 2
    expr: 語法錯誤
    [njust@njust tutorials]$ expr 5 \* 2
    10
    
  • 在shell腳本中expr命令也同樣復(fù)雜,如下所示:
    #!/bin/bash
    
    var1=10
    var2=20
    var3=$(expr $var2 / $var1)  # 要將一個數(shù)學(xué)表達式的結(jié)果賦值給一個變量var3,也需要借助命令替換看杭。
    echo The result is $var3
    
    # 結(jié)果
    The result is 2
    
  • 在bash中忠藤,在將一個數(shù)學(xué)運算結(jié)果賦給一個變量時,可以使用美元符和[]將整個表達式圈起來楼雹。
    [njust@njust tutorials]$ var1=$[1+34]
    [njust@njust tutorials]$ echo $var1
    35
    
  • 用方括號執(zhí)行shell運算比用expr命令方便很多模孩,在shell腳本中也能看出。
    #!/bin/bash
    
    var1=10
    var2=20
    
    
    var3=`expr $var2 / $var1`
    echo the result is $var3
    
    var1=100
    var2=200
    var3=45
    
    
    var4=$[$var1 * ($var3 - $var2)]
    echo final result is $var4
    # 結(jié)果
    the result is 2
    final result is -15500
    
  • bash shell數(shù)學(xué)運算符只支持整數(shù)運算贮缅,這是一個巨大的限制榨咐。
    #!/bin/bash
    
    var1=100
    var2=45
    var3=$[$var1 / $var2]
    echo The final result is $var3
    
    # 結(jié)果
    The final result is 2
    
  • 浮點數(shù)運算的解決方案:使用內(nèi)建的bash計算器bc。bash計算器允許在命令行中輸入浮點表達式谴供,然后解釋并計算該表達式块茁,返回結(jié)果。
  • 浮動運算是由內(nèi)建變量scale控制的桂肌,這個值設(shè)置為你需要保留的小數(shù)點后幾位数焊。
    [njust@njust ~]$ bc -q  # -q參數(shù)表示不顯示歡迎信息
    3.44 /5
    0
    scale=4
    3.44 / 5
    .6880
    quit
    
  • bash計算器還支持變量,如下所示:
    bc -q  
    var1=10
    var1*4
    40
    var2=var1 / 5
    print var2
    2
    quit
    
  • 在腳本中使用bc:可以使用命令替換運行bc命令崎场,并將輸出賦值給一個變量佩耳,基本格式如下:
    變量名=$(echo "可選項; 表達式" | bc)
    
  • 實例:在腳本中使用bc,如下所示谭跨。
    #!/bin/bash
    
    var1=$(echo "scale=4; 3.44/5" | bc)
    echo $var1
    .6880
    
  • 上述方法適用于較短的運算蚕愤,但有時候涉及更多的數(shù)字。需要進行大量的運算饺蚊,在一個命令行中列出多個表達式就會麻煩。解決方法:使用內(nèi)聯(lián)輸入重定向悬嗓,它允許你直接在命令行中重定向數(shù)據(jù)污呼。基本格式為:
    變量名=$(bc << EOF
    可選項
    語句
    表達式
    EOF)
    
  • 在bash計算器中創(chuàng)建的變量只在bash計算器中有效包竹,不能在shell腳本中使用燕酷。
    #!/bin/bash
    
    
    var1=10.46
    var2=43.67
    var3=33.2
    var4=71
    
    var5=$(bc << EOF
    scale=4
    a1 = ($var1 * $var2)
    b1 = ($var3 * $var4)
    a1 + b1
    EOF
    )
    echo final result is $var5
    # 結(jié)果
    final result is 2813.9882
    

8.退出腳本

  • shell中運行的每個命令都使用退出狀態(tài)碼籍凝,shell告訴它已經(jīng)運行完畢。退出狀態(tài)碼是一個0到255的整數(shù)值苗缩,在命令結(jié)束時由命令傳給shell饵蒂,可以捕捉這個值在腳本中使用。**Linux專門提供了變量?來保存上一個已執(zhí)行命令的退出狀態(tài)碼**酱讶。對于需要進行檢查的命令退盯,必須在其運行完畢后立即查看或使用?變量。
    [njust@njust tutorials]$ date
    2020年 03月 12日 星期四 10:39:19 CST
    [njust@njust tutorials]$ echo $?
    0
    
  • Linux退出狀態(tài)碼如下:
    0           命令成功結(jié)束
    1           一般性未知錯誤
    2           不適合的shell命令
    126         命令不可執(zhí)行
    127         沒找到命令
    128         無效的退出參數(shù)
    130         通過CTRL+C終止的命令
    
  • exit命令:默認情況下泻肯,shell腳本會以腳本中最后一個命令的退出狀態(tài)碼退出渊迁。用戶可以改變這種默認行為,返回自己的狀態(tài)碼灶挟。eixt命令允許在腳本結(jié)束時指定一個退出狀態(tài)碼琉朽。
    #!/bin/bash
    
    var1=10
    var2=30
    var3=$[$var1 + $var2]
    echo The answer is $var3
    exit 5
    
    # 結(jié)果
    The answer is 40
    echo $?
    5
    
    # 也可以在exit命令的參數(shù)中使用變量
    exit $var3
    
    echo $?
    40
    
    # 注意:退出狀態(tài)碼最大為255,超過最大的255后稚铣,會通過取模運算得到最后的結(jié)果即實際值 % 256 = 最結(jié)果
    var1=10
    var2=30
    var3=$[$var1 * $var2]
    echo The answer is $var3
    exit $var3
    
    echo $?
    44
    

9.資料下載

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市惕医,隨后出現(xiàn)的幾起案子耕漱,更是在濱河造成了極大的恐慌,老刑警劉巖曹锨,帶你破解...
    沈念sama閱讀 221,576評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件孤个,死亡現(xiàn)場離奇詭異,居然都是意外死亡沛简,警方通過查閱死者的電腦和手機齐鲤,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,515評論 3 399
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來椒楣,“玉大人给郊,你說我怎么就攤上這事∨趸遥” “怎么了淆九?”我有些...
    開封第一講書人閱讀 168,017評論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長毛俏。 經(jīng)常有香客問我炭庙,道長,這世上最難降的妖魔是什么煌寇? 我笑而不...
    開封第一講書人閱讀 59,626評論 1 296
  • 正文 為了忘掉前任焕蹄,我火速辦了婚禮,結(jié)果婚禮上阀溶,老公的妹妹穿的比我還像新娘腻脏。我一直安慰自己鸦泳,他們只是感情好,可當我...
    茶點故事閱讀 68,625評論 6 397
  • 文/花漫 我一把揭開白布永品。 她就那樣靜靜地躺著做鹰,像睡著了一般。 火紅的嫁衣襯著肌膚如雪鼎姐。 梳的紋絲不亂的頭發(fā)上钾麸,一...
    開封第一講書人閱讀 52,255評論 1 308
  • 那天,我揣著相機與錄音症见,去河邊找鬼喂走。 笑死,一個胖子當著我的面吹牛谋作,可吹牛的內(nèi)容都是我干的芋肠。 我是一名探鬼主播,決...
    沈念sama閱讀 40,825評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼遵蚜,長吁一口氣:“原來是場噩夢啊……” “哼帖池!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起吭净,我...
    開封第一講書人閱讀 39,729評論 0 276
  • 序言:老撾萬榮一對情侶失蹤睡汹,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后寂殉,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體囚巴,經(jīng)...
    沈念sama閱讀 46,271評論 1 320
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,363評論 3 340
  • 正文 我和宋清朗相戀三年友扰,在試婚紗的時候發(fā)現(xiàn)自己被綠了彤叉。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,498評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡村怪,死狀恐怖秽浇,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情甚负,我是刑警寧澤柬焕,帶...
    沈念sama閱讀 36,183評論 5 350
  • 正文 年R本政府宣布,位于F島的核電站梭域,受9級特大地震影響斑举,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜病涨,卻給世界環(huán)境...
    茶點故事閱讀 41,867評論 3 333
  • 文/蒙蒙 一懂昂、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧没宾,春花似錦凌彬、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,338評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至会钝,卻和暖如春伐蒋,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背迁酸。 一陣腳步聲響...
    開封第一講書人閱讀 33,458評論 1 272
  • 我被黑心中介騙來泰國打工先鱼, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人奸鬓。 一個月前我還...
    沈念sama閱讀 48,906評論 3 376
  • 正文 我出身青樓焙畔,卻偏偏與公主長得像,于是被迫代替她去往敵國和親串远。 傳聞我的和親對象是個殘疾皇子宏多,可洞房花燭夜當晚...
    茶點故事閱讀 45,507評論 2 359

推薦閱讀更多精彩內(nèi)容

  • bash中變量的種類 局部變量:生效范圍為當前shell進程,對當前shell之外的其它shell進程澡罚,包括當前s...
    毛利卷卷發(fā)閱讀 414評論 0 1
  • 一.編程基本概念 編程邏輯處理方式: 順序執(zhí)行 循環(huán)執(zhí)行 選擇執(zhí)行 ?shell編程:過程式伸但、解釋執(zhí)行編程語言的基...
    楠人幫閱讀 1,380評論 0 1
  • 基礎(chǔ)篇 一、輸出信息 大部分 Shell 命令都會生成自己的輸出信息留搔,在腳本運行時打印到終端屏幕上更胖。但是很多時候,...
    rollingstarky閱讀 595評論 0 1
  • 程序:什么是程序 程序是指令加數(shù)據(jù)來組合來完成 真正關(guān)心的是對數(shù)據(jù)的處理隔显,通過指令對數(shù)據(jù)的操作 程序編程風(fēng)格 在程...
    數(shù)據(jù)革命閱讀 437評論 0 0
  • 本地啟動redis控制臺 && 安裝redis服務(wù)(用于調(diào)試) 1.下載最新版redis却妨,選擇.zip則是免安裝的...
    Lulus閱讀 1,550評論 0 1