Shell腳本編程(一)

shell 腳本編程(一)

1 . shell 的做用

  • Shell的做用是解釋執行用戶的命令,用戶輸入一條命令,Shell就解釋執行一條,這種方式稱爲交互式(Interactive),Shell還有一種執行命令的方式稱爲批處理(Batch),用戶事先寫一個Shell腳本(Script),其中有不少條命令,讓Shell一次把這些命令執行完,而沒必要一條一條地敲命令。Shell腳本和編程語言很類似,也有變量和流程控制語句,但Shell腳本是解釋執行的,不須要編譯,Shell程序從腳本中一行一行讀取並執行這些命令,至關於一個用戶把腳本中的命令一行一行敲到Shell提示符下執行。shell

  • 用戶在命令行輸入命令後, 通常狀況下Shell 回fork一個子進程並exec該命令, 可是shell的內建命令例外, 執行內建命令至關與調用shell進程中的一個函數, 並不會建立新的進程, 例如:cd、alias、umask、exit 等命令都是內建命令, 凡是用which 命令查不到程序文件所在位置的命令都是內建命令, 內建命令沒有單獨的man手冊, 要在man手冊中查看內建命令, 應該用編程

    # 查看內建的命令
    $ man bash-builtins
  • 寫一個簡單的shell腳本, t1.shbash

    #!/bin/sh
    cd ..
    ls

    說明:編程語言

    shell 腳本中用# 表示註釋, 至關於C語言的//註釋, 但若是#位於第一行開頭, 而且是 #!(稱爲Shenbang)則例外, 它表示該腳本使用後面指定的解釋器/bin/sh解釋執行。 若是把這個腳本文件加上課執行權限而後執行函數

    chmod a+x t1.sh
    # 經過 ./ 執行shell腳本
    ./t1.sh

    說明:ui

    Shell 會fork一個子進程並調用exec執行 ./t1.sh這個程序, exec系統調應該把子進程的代碼段替換成 ./t1.sh 程序的代碼段, 並從它的 _start 開始執行, 然而 t1.sh 是個文本文件, 根本沒有代碼段和 _start 函數, 那怎麼辦??命令行

    其實exec 還有另外以一種機制, 若是要執行的是一個文本文件, 而且第一行用Shebang指定的解釋器, 則用解釋器程序的代碼段替換當前進程, 而且從解釋器的 _start 開始執行, 而這個文本文件被看成命令參數傳給解釋器, 所以, 執行上述腳本至關於執行程序。code

  • 執行shell 腳本的方式:進程

    # 經過source 命令執行.sh文件
    $ source t1.sh
    # 若是給文件添加了可執行權限, 能夠經過一下方式執行shell 腳本
    $ chmod a+x t1.sh # 給該文件添加可執行權限
    # 經過./執行腳本
    $ ./t1.sh
    #直接用解釋器去執行該文件
    $ /bin/sh ./t1.sh

  • 若是將命令行下輸入的命令用()括起來, 這樣也會fork 一個子Shell 執行 ()括號中的命令, 一行能夠輸入由分號 ;隔開多條命令。ip

    [czk@localhost ~]$ (cd ..;ls -l)
    total 0
    drwx------. 2 czk czk 98 May 18 22:50 czk
  • 若是沒有用括號將命令括起來, 則是在當前的shell進程進行執行, 並不會fork一個子進程進行去執行該命令。

2.基本變量

變量的類型

  • 本地變量

    只存在於當前Shell進程, 用set命令能夠顯示當前shell進程中定義的全部變量, 包括本地變量、環境變量和函數。

    # 定義本地變量, 等號 = 兩邊不能由空格,變量名通常用大寫+下劃線組成
    [czk@localhost ~]$ VARNAME=czk
  • 環境變量

    環境變量能夠從父進程傳給子進程, 所以Shell進程的環境變量能夠從當前shell進程傳給fork出來的子進程。用printenv命令能夠顯示當前Shell進程的環境變量。

    # 使用export 命令能夠將本地變量導出爲環境變量
    [czk@localhost ~]$ export VARNAME=czk
    # 使用 unset 命令能夠刪除本地或環境變量
    [czk@localhost ~]$ unset VARNAME
    [czk@localhost ~]$ echo ${VARNAME}
    # 空。。。。

    變量能夠經過 $ 或者 ${varname} 進行取值

    注意,在定義變量時不用$,取變量值時要用$。和C語言不一樣的是,Shell變量不須要明肯定義類型,事實上Shell變量的值都是字符串,好比咱們定義VAR=45,其實VAR的值是字符串45而非整數。Shell變量不須要先定義後使用,若是對一個沒有定義的變量取值,則值爲空字符串。

3.命令代換

` 或者 $()

由 反引號 括起來的也是一條命令, Shell 先執行該命令, 而後將輸出結果馬上代換到當前命令行中。以下:

# date 日期函數
[czk@localhost ~]$ DATE=`date`
[czk@localhost ~]$ echo $DATE
Sat May 18 23:45:47 EDT 2019
# $() 方式
[czk@localhost ~]$ DATE=$(date)
[czk@localhost ~]$ echo $DATE
Sat May 18 23:47:20 EDT 2019

4.文件名代換

主要是用通配符就將文件匹配替換

* :匹配0個或者多個任意字符
 ?:匹配一個任意字符
 [若干字符] : 匹配方括號中任意一個字符的一次出現

5.算術代換

$(())

這個是用來進行算術運算, $(()) 中的shell 變量取值將轉換成整數, 以下:

# $(())中只能用+-*/和()運算符,而且只能作整數運算。
[czk@localhost ~]$ NUM=99
[czk@localhost ~]$ echo $(($NUM+1))
100

6.轉義字符

\ 在shell中被用做轉義字符用於去除緊跟其後的單個字符的特殊意義,

好比建立一個"$ $" 的文件

[czk@localhost ~]$ touch \$\ \$
[czk@localhost ~]$ ls
$ $  test.sh

還有一個字符也比較特殊, 它沒有說明特殊含義, 可是用來作文件名也是比較麻煩的, 那就是 - 號。

它會把和它連在一塊兒的字符, 當成了命令行參數的命令選項了,若是你硬要用 它來做文件名, 能夠有以下兩種方式:

[czk@localhost ~]$ touch ./-hi
[czk@localhost ~]$ ls
$ $  -hi  test.sh

OR

[czk@localhost ~]$ touch -- -hello
[czk@localhost ~]$ ls
$ $  -hello  -hi  test.sh

7.單引號和雙引號

Shell 腳本中的單引號和雙引號同樣都是字符串的界定符,而不是字符的界定符, 單引號用於保存引號內全部字符的字面值, 即便引號內的\和回車也不例外,可是字符串中不能出現單引號。若是引號沒有配對就輸入回車,Shell會給出續行提示符,要求用戶把引號配上對。

[czk@localhost ~]$ echo '$SHELL'
$SHELL

被雙引號用括住的內容,將被視爲單一字串。它防止通配符擴展,但容許變量擴展。這點與單引號的處理方式不一樣。

[czk@localhost ~]$ DATE=$(date)
# 若是是雙引號, 還會繼續展開裏面的內容
[czk@localhost ~]$ echo "$DATE"
Sun May 19 02:31:05 EDT 2019
[czk@localhost ~]$ echo '$DATE'
$DATE
相關文章
相關標籤/搜索