shell腳本編程基礎(chǔ)

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

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

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

1.使用多個(gè)命令

  • shell腳本的關(guān)鍵之處在于輸入多個(gè)命令并處理每個(gè)命令的結(jié)果,甚至需要將一個(gè)命令的結(jié)果傳給另一個(gè)命令。shell可以讓多個(gè)命令串起來,一次執(zhí)行。如果要兩個(gè)命令一起運(yùn)行,可以將它們放在同一行,之間用逗號(hào)隔開。
    [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)
    
  • 上述方法的缺點(diǎn):使用上述方法可以將任意多個(gè)命令串聯(lián)在一起使用,最大命令行字符數(shù)不超過255個(gè)。對(duì)小型的腳本適用,當(dāng)有很多腳本時(shí),直接在命令行中輸入整個(gè)命令就很麻煩。

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

  • 創(chuàng)建shell腳本文件時(shí),必須在文件的第一行指定使用的shell是哪種類型,格式為:
    #!/bin/bash
    
  • shell腳本中注釋一般以#開頭,shell腳本不會(huì)處理注釋的行。但是,shell腳本的第一行是例外。#后的!會(huì)告訴shell用哪個(gè)shell來運(yùn)行腳本,shell會(huì)根據(jù)命令在文件中出現(xiàn)的先后順序進(jìn)行處理。下面是創(chuàng)建腳本名為demo的文件。
    #!/bin/bash
    date
    who
    
  • 存在的問題:如何讓bash shell找到你創(chuàng)建的腳本文件?shell會(huì)通過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找到腳本文件,有兩個(gè)方法:
    • 將shell腳本文件所處的目錄添加到PATH環(huán)境變量中;
    • 在命令行中使用絕對(duì)或相對(duì)的路徑來引用shell腳本文件(常用);
  • 由于你還沒有執(zhí)行文件的權(quán)限,這是由于umask變量被設(shè)置為022,因此系統(tǒng)創(chuàng)建的文件只有讀寫權(quán)限。使用下面的命令賦予文件有可執(zhí)行權(quán)限。
    chmod u+x demo
    
  • 為了引用當(dāng)前目錄下的文件,可以在shell中使用單點(diǎn)操作符.。正式執(zhí)行腳本demo
    ./demo
    

3.顯示消息

  • 在echo命令后加上一個(gè)字符串,該命令就會(huì)顯示出這個(gè)文本字符串。默認(rèn)情況下,不需要使用引號(hào)將需要顯示的字符串包含起來。
    [njust@njust tutorials]$ echo hello world
    hello world
    
  • 當(dāng)字符串中含有單引號(hào)或雙引號(hào)時(shí),可以使用雙引號(hào)或單引號(hào)(注意敘述的順序)包含該字符串。
    [njust@njust tutorials]$ echo "Let's see if this'll work"
    Let's see if this'll work
    
  • echo命令可以添加到shell腳本中任何需要顯示額外信息的地方!
  • 當(dāng)需要把字符串和命令輸出顯示在同一行時(shí),可以使用帶參數(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.使用變量

  • 變量可以將臨時(shí)信息存儲(chǔ)在shell腳本中,便于和shell中其他的命令一起使用。
  • 環(huán)境變量:shell維護(hù)一組環(huán)境變量,用來記錄特定的系統(tǒng)信息。可以使用set命令來顯示一份完整的當(dāng)前環(huán)境變量列表
  • 在腳本中,可以在環(huán)境變量名稱前加上美元符號(hào)$從而來使用這些變量。
    #!/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)境變量會(huì)在腳本運(yùn)行時(shí)替換成當(dāng)前值,只要腳本在引號(hào)中出現(xiàn)美元符,它就會(huì)以為你在引用一個(gè)變量,因此在表示真實(shí)美元的含義時(shí),需要在$符號(hào)前加\轉(zhuǎn)義字符。
    #!/bin/bash 
    
    echo "The cost of the item is \$5."
    
  • 此外,還可以通過${變量名}的形式引用變量,變量名兩側(cè)的{}通常用于幫助識(shí)別美元符后的變量名。
  • 用戶變量:除了環(huán)境變量外,shell還允許在腳本中定義和使用自己的變量。變量名使用字母、數(shù)字或下劃線組成的字符串表示,長度最長不超過20個(gè)。
  • 注意:使用等號(hào)將值賦給用戶自定義的變量,在變量、等號(hào)和值之間不能出現(xiàn)空格?。。?
    var1=23  # 等號(hào)左右不能出現(xiàn)空格??!
    var2=demo
    var3=testing
    var4="hello shell"
    
  • shell腳本會(huì)自動(dòng)決定變量值的數(shù)據(jù)類型。在腳本的整個(gè)生命周期內(nèi),shell腳本定義的變量會(huì)一直存在,在shell腳本結(jié)束時(shí)會(huì)被刪除。用戶變量也可以通過$引用。
    #!/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
    
  • 變量每次引用時(shí),都會(huì)輸出當(dāng)前賦給它的值。引用一個(gè)變量時(shí)需要使用美元符號(hào)$,引用一個(gè)變量var1給另一個(gè)變量var2進(jìn)行賦值時(shí),被賦值的變量不要使用$。對(duì)var1忘記使用$號(hào),就會(huì)使var2的賦值行變成普通的字符串。
    #!/bin/bash
    
    var1=10
    var2=$var1  # 在賦值語句中使用var1變量的值時(shí),必須使用$符號(hào)
    echo The resulting value is $var2
    
    # 結(jié)果 
    The resulting value is 10
    
    var2=var1;  # 錯(cuò)誤的代表案例,輸出結(jié)果是普通字符串
    echo The resulting value is $var2
    
    # 錯(cuò)誤結(jié)果 
    The resulting value is var1
    
  • 命令替換:shell最有用的特性之一是從命令輸出中提取出信息,并將其賦值給變量。將命令的輸出賦值給變量后,就可以在腳本中使用了。有兩種方法可以將命令輸出賦值給變量:
    • 反引號(hào)字符`
    • $()格式
  • 命令替換允許你將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
    
  • 實(shí)例:通過命令替換獲得當(dāng)前日期并用它來生成唯一的文件名。
    #!/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日志文件
    
  • 命令替換會(huì)創(chuàng)建一個(gè)子shell來運(yùn)行對(duì)應(yīng)的命令,由該子shell所執(zhí)行命令是無法使用腳本中所創(chuàng)建的變量。在命令行中使用路徑./運(yùn)行命令時(shí),也會(huì)創(chuàng)建子shell;在運(yùn)行命令時(shí)不加入路徑,就不會(huì)創(chuàng)建子shell。

5.重定向輸入和輸出

  • 重定向目的:想要保存某個(gè)命令的輸出而不僅僅是讓結(jié)果輸出在屏幕上。
  • 輸出重定向:最基本的重定向是將命令的輸出發(fā)送在一個(gè)文件中。格式如下:
    具體命令 > 輸出文件名
    
  • 實(shí)例如下:
    [njust@njust tutorials]$ date > test6
    [njust@njust tutorials]$ cat test6
    2020年 03月 12日 星期四 09:40:09 CST
    
  • 如果輸出文件已經(jīng)存在,重定向操作符會(huì)用新的文件數(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)
    
  • 有時(shí)候,你并不想覆蓋原始文件中的內(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)容重定向到命令,而不是將命令輸出重定向到文件。輸入重定向的格式:
    具體命令 < 輸入文件
    
  • 具體實(shí)例:wc命令可以統(tǒng)計(jì)文件中的數(shù)據(jù),默認(rèn)情況下會(huì)輸出3個(gè)值。
    [njust@njust tutorials]$ wc < test6
    4  21 186  # 從左到右分別表示文本的行數(shù)、文本的詞數(shù)、文本的字節(jié)數(shù)
    
  • 內(nèi)聯(lián)輸入重定向:<<無需使用文件進(jìn)行重定向,只需要在命令行中指定輸入重定向的數(shù)據(jù)即可。注意:必須指定一個(gè)文本標(biāo)記來劃分輸入數(shù)據(jù)的起始和結(jié)尾。任何字符串都可以作為文本標(biāo)記,但數(shù)據(jù)的起始和結(jié)尾文本標(biāo)記必須一致。格式:
    具體命令 >> EOF
    data
    EOF
    
  • 在命令行中使用內(nèi)聯(lián)輸入重定向時(shí),shell會(huì)用PS2變量中定義的次提示符來提示用戶輸入數(shù)據(jù)。
    [njust@njust tutorials]$ wc << EOF
    > test string 1  # >表示的就是次提示符
    > test string 2
    > test string 3
    > EOF
    3  9 42
    

6.管道

  • 管道的目的:一個(gè)命令的輸出作為另一個(gè)命令的輸入。
  • 管道被放在命令之間,將一個(gè)命令的輸出重定向到另一個(gè)命令中?;靖袷饺缦拢?
    命令1 | 命令2
    
  • 管道串器的兩個(gè)命令不是依次執(zhí)行的,Linux系統(tǒng)實(shí)際上會(huì)同時(shí)運(yùn)行這兩個(gè)命令,在系統(tǒng)內(nèi)部將它們連接起來。在第一個(gè)命令產(chǎn)生輸出的同時(shí),輸出會(huì)被立即送個(gè)第二個(gè)命令。數(shù)據(jù)傳輸不會(huì)用的任何中間文件或緩沖區(qū)。
  • 可以在一條命令中使用任意多條管道??梢猿掷m(xù)地將命令的輸出通過管道傳給其他命令來細(xì)化操作。如下例所示:
    rpm -qa | sort | more  # 先生成已安裝包的列表,再排序,最后再用more顯示
    
    # 如果想更精致點(diǎn),可以搭配使用重定向和管道將輸出保存到文件中
    rpm -qa | sort > rpm.list
    
  • 管道最流行的用法之一就是將產(chǎn)生的大量輸出通過管道傳給more命令,一般與ls命令結(jié)合使用。

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

  • 在shell中有兩個(gè)途徑進(jìn)行數(shù)學(xué)運(yùn)算。
    • expr命令
    • 使用方括號(hào)
  • expr命令允許在命令行中處理數(shù)學(xué)表達(dá)式,但特別笨拙。許多expr命令操作符在shell中另有含義,當(dāng)它們出現(xiàn)在expr命令中時(shí),會(huì)得到一些詭異的結(jié)果。對(duì)那些容易被shell錯(cuò)誤解釋的字符,需要使用轉(zhuǎn)義字符。
    [njust@njust tutorials]$ expr 5 * 2
    expr: 語法錯(cuò)誤
    [njust@njust tutorials]$ expr 5 \* 2
    10
    
  • 在shell腳本中expr命令也同樣復(fù)雜,如下所示:
    #!/bin/bash
    
    var1=10
    var2=20
    var3=$(expr $var2 / $var1)  # 要將一個(gè)數(shù)學(xué)表達(dá)式的結(jié)果賦值給一個(gè)變量var3,也需要借助命令替換。
    echo The result is $var3
    
    # 結(jié)果
    The result is 2
    
  • 在bash中,在將一個(gè)數(shù)學(xué)運(yùn)算結(jié)果賦給一個(gè)變量時(shí),可以使用美元符和[]將整個(gè)表達(dá)式圈起來。
    [njust@njust tutorials]$ var1=$[1+34]
    [njust@njust tutorials]$ echo $var1
    35
    
  • 用方括號(hào)執(zhí)行shell運(yùn)算比用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é)運(yùn)算符只支持整數(shù)運(yùn)算,這是一個(gè)巨大的限制。
    #!/bin/bash
    
    var1=100
    var2=45
    var3=$[$var1 / $var2]
    echo The final result is $var3
    
    # 結(jié)果
    The final result is 2
    
  • 浮點(diǎn)數(shù)運(yùn)算的解決方案:使用內(nèi)建的bash計(jì)算器bc。bash計(jì)算器允許在命令行中輸入浮點(diǎn)表達(dá)式,然后解釋并計(jì)算該表達(dá)式,返回結(jié)果。
  • 浮動(dòng)運(yùn)算是由內(nèi)建變量scale控制的,這個(gè)值設(shè)置為你需要保留的小數(shù)點(diǎn)后幾位。
    [njust@njust ~]$ bc -q  # -q參數(shù)表示不顯示歡迎信息
    3.44 /5
    0
    scale=4
    3.44 / 5
    .6880
    quit
    
  • bash計(jì)算器還支持變量,如下所示:
    bc -q  
    var1=10
    var1*4
    40
    var2=var1 / 5
    print var2
    2
    quit
    
  • 在腳本中使用bc:可以使用命令替換運(yùn)行bc命令,并將輸出賦值給一個(gè)變量,基本格式如下:
    變量名=$(echo "可選項(xiàng); 表達(dá)式" | bc)
    
  • 實(shí)例:在腳本中使用bc,如下所示。
    #!/bin/bash
    
    var1=$(echo "scale=4; 3.44/5" | bc)
    echo $var1
    .6880
    
  • 上述方法適用于較短的運(yùn)算,但有時(shí)候涉及更多的數(shù)字。需要進(jìn)行大量的運(yùn)算,在一個(gè)命令行中列出多個(gè)表達(dá)式就會(huì)麻煩。解決方法:使用內(nèi)聯(lián)輸入重定向,它允許你直接在命令行中重定向數(shù)據(jù)。基本格式為:
    變量名=$(bc << EOF
    可選項(xiàng)
    語句
    表達(dá)式
    EOF)
    
  • 在bash計(jì)算器中創(chuàng)建的變量只在bash計(jì)算器中有效,不能在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中運(yùn)行的每個(gè)命令都使用退出狀態(tài)碼,shell告訴它已經(jīng)運(yùn)行完畢。退出狀態(tài)碼是一個(gè)0到255的整數(shù)值,在命令結(jié)束時(shí)由命令傳給shell,可以捕捉這個(gè)值在腳本中使用。**Linux專門提供了變量?來保存上一個(gè)已執(zhí)行命令的退出狀態(tài)碼**。對(duì)于需要進(jìn)行檢查的命令,必須在其運(yùn)行完畢后立即查看或使用?變量。
    [njust@njust tutorials]$ date
    2020年 03月 12日 星期四 10:39:19 CST
    [njust@njust tutorials]$ echo $?
    0
    
  • Linux退出狀態(tài)碼如下:
    0           命令成功結(jié)束
    1           一般性未知錯(cuò)誤
    2           不適合的shell命令
    126         命令不可執(zhí)行
    127         沒找到命令
    128         無效的退出參數(shù)
    130         通過CTRL+C終止的命令
    
  • exit命令:默認(rèn)情況下,shell腳本會(huì)以腳本中最后一個(gè)命令的退出狀態(tài)碼退出。用戶可以改變這種默認(rèn)行為,返回自己的狀態(tài)碼。eixt命令允許在腳本結(jié)束時(shí)指定一個(gè)退出狀態(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后,會(huì)通過取模運(yùn)算得到最后的結(jié)果即實(shí)際值 % 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)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

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

友情鏈接更多精彩內(nèi)容