Shell指令碼基礎知識

2021-09-22 17:57:27 字數 5158 閱讀 7656

◆1.1 語法基本介紹

1.1.1 開頭

程式必須以下面的行開始(必須方在檔案的第一行):

#!/bin/sh

符號#!用來告訴系統它後面的引數是用來執行該檔案的程式。在這個例子中我們使用/bin/sh來執行程式。

當編輯好指令碼時,如果要執行該指令碼,還必須使其可執行。

要使指令碼可執行:

編譯 chmod +x filename 這樣才能用./filename 來執行

1.1.2 注釋

在進行shell程式設計時,以#開頭的句子表示注釋,直到這一行的結束。我們真誠地建議您在程式中使用注釋。

如果您使用了注釋,那麼即使相當長的時間內沒有使用該指令碼,您也能在很短的時間內明白該指令碼的作用及工作原理。

1.1.3 變數

在其他程式語言中您必須使用變數。在shell程式設計中,所有的變數都由字串組成,並且您不需要對變數進行宣告。要賦值給乙個變數,您可以這樣寫:

#!/bin/sh

#對變數賦值:

a="hello world"

# 現在列印變數a的內容:

echo "a is:"

echo $a

有時候變數名很容易與其他文字混淆,比如:

num=2

echo "this is the $numnd"

這並不會列印出"this is the 2nd",而僅僅列印"this is the ",因為shell會去搜尋變數numnd的值,但是這個變數時沒有值的。可以使用花括號來告訴shell我們要列印的是num變數:

num=2

echo "this is the $nd"

這將列印: this is the 2nd

1.1.4 環境變數

由export關鍵字處理過的變數叫做環境變數。我們不對環境變數進行討論,因為通常情況下僅僅在登入指令碼中使用環境變數。

【什麼是shell】

簡單點理解,就是系統跟計算機硬體互動時使用的中間介質,它只是系統的乙個工具。實際上,在shell和計算機硬體之間還有一層東西那就是系統核心了。打個比方,如果把計算機硬體比作乙個人的軀體,而系統核心則是人的大腦,至於shell,把它比作人的五官似乎更加貼切些。

回到計算機上來,使用者直接面對的不是計算機硬體而是shell,使用者把指令告訴shell,然後shell再傳輸給系統核心,接著核心再去支配計算機硬體去執行各種操作。

筆者接觸的linux發布版本(redhat/centos)系統預設安裝的shell叫做bash,即bourne again shell,它是sh(bourne shell)的增強版本。bourn shell 是最早行起來的乙個shell,創始人叫steven bourne,為了紀念他所以叫做bourn shell,檢稱sh。那麼這個bash有什麼特點呢?

1)記錄命令歷史

我們敲過的命令,linux是會有記錄的,預設可以記錄1000條歷史命令。這些命令儲存在使用者的家目錄中的.bash_history檔案中。

有一點需要你知道的是,只有當使用者正常退出當前shell時,在當前shell中執行的命令才會儲存至.bash_history檔案中。

與命令歷史有關的有乙個有意思的字元那就是」!」了。常用的有這麼幾個應用:

(1)!! (連續兩個」!」),表示執行上一條指令;(2)!

n(這裡的n是數字),表示執行命令歷史中第n條指令,例如」!100」表示執行命令歷史中第100個命令;(3)!字串(字串大於等於1),例如!

ta,表示執行命令歷史中最近一次以ta為開頭的指令。

2)指令和檔名補全

在本教程最開始筆者就介紹過這個功能了,記得嗎?對了就是按tab鍵,它可以幫你補全乙個指令,也可以幫你補全乙個路徑或者乙個檔名。連續按兩次tab鍵,系統則會把所有的指令或者檔名都列出來。

3)別名

前面也出現過alias的介紹,這個就是bash所特有的功能之一了。我們可以通過alias把乙個常用的並且很長的指令別名乙個簡潔易記的指令。如果不想用了,還可以用unalias解除別名功能。

直接敲alias會看到目前系統預設的alias :

看到了吧,系統預設的alias指令也就這幾個而已,你也可以自定義你想要的指令別名。alias語法很簡單,alias [命令別名]=[』具體的命令』]。

4)萬用字元

在bash下,可以使用*來匹配零個或多個字元,而用?匹配乙個字元。

5)輸入輸出從定向

輸入重定向用於改變命令的輸入,輸出重定向用於改變命令的輸出。輸出重定向更為常用,它經常用於將命令的結果輸入到檔案中,而不是螢幕上。輸入重定向的命令是<,輸出重定向的命令是》,另外還有錯誤重定向2>,以及追加重定向》,稍後會詳細介紹。

6)管道符

前面已經提過過管道符」|」,就是把前面的命令執行的結果丟給後面的命令。

7)作業控制。

當執行乙個程序時,你可以使它暫停(按ctrl+z),然後使用fg命令恢復它,利用bg命令使他到後台執行,你也可以使它終止(按ctrl+c)。

【變數】

前面章節中筆者曾經介紹過環境變數path,這個環境變數就是shell預設的乙個變數,通常shell預設的變數都是大寫的。變數,說簡單點就是使用乙個較簡單的字串來替代某些具有特殊意義的設定以及資料。就拿path來講,這個path就代替了所有常用命令的絕對路徑的設定。

因為有了path這個變數,所以我們執行某個命令時不再去輸入全域性路徑,直接敲命令名即可。你可以使用echo命令顯示變數的值。

除了path, home, logname外,系統預設的環境變數還有哪些呢?

使用env命令即可全部列出系統預設的全部系統變數了。不過登入的使用者不一樣這些環境變數的值也不一樣。當前顯示的就是root這個賬戶的環境變數了。

下面筆者簡單介紹一下常見的環境變數:

path 決定了shell將到哪些目錄中尋找命令或程式

home 當前使用者主目錄

histsize 歷史記錄數

logname 當前使用者的登入名

hostname 指主機的名稱

shell 前使用者shell型別

lang 語言相關的環境變數,多語言可以修改此環境變數

mail 當前使用者的郵件存放目錄

pwd 當前目錄

env命令顯示的變數只是環境變數,系統預設的變數其實還有很多,你可以使用set命令把系統預設的全部變數都顯示出來。

限於篇幅,筆者在上例中並沒有把所有顯示結果都截圖。set不僅可以顯示系統預設的變數,也可以連同使用者自定義的變數顯示出來。使用者自定義變數?是的,使用者自己同樣可以定義變數。

雖然你可以自定義變數,但是該變數只能在當前shell中生效,不信你再登入乙個shell試試?

使用bash命令即可再開啟乙個shell,此時先前設定的myname變數已經不存在了,退出當前shell回到原來的shell,myname變數還在。那要想設定的變數一直生效怎麼辦?有兩種情況:

1) 要想系統內所有使用者登入後都能使用該變數

需要在/etc/profile檔案最末行加入 「export myname=aming」 然後執行」source /etc/profile」就可以生效了。此時你再執行bash命令或者直接su - test賬戶看看。

2)只想讓當前使用者使用該變數

需要在使用者主目錄下的.bashrc檔案最後一行加入「export myname=aming」 然後執行」source .bashrc」就可以生效了。

這時候再登入test賬戶,myname變數則不會生效了。上面用的source命令的作用是,講目前設定的配置重新整理,即不用登出再登入也能生效。

筆者在上例中使用」myname=aming」來設定變數myname,那麼在linux下設定自定義變數有哪些規則呢?

a. 設定變數的格式為」a=b」,其中a為變數名,b為變數的內容,等號兩邊不能有空格;

b. 變數名只能由英、數字以及下劃線組成,而且不能以數字開頭;

c. 當變數內容帶有特殊字元(如空格)時,需要加上單引號;

有一種情況,需要你注意,就是變數內容中本身帶有單引號,這就需要用到雙引號了。

d. 如果變數內容中需要用到其他命令執行結果則可以使用反引號;

e. 變數內容可以累加其他變數的內容,需要加雙引號;

在這裡如果你不小心把雙引號加錯為單引號,將得不到你想要的結果

通過上面幾個例子也許你能看得出,單引號和雙引號的區別:用雙引號時不會取消掉裡面出現的特殊字元的本身作用(這裡的$),而使用單引號則裡面的特殊字元全部失去它本身的作用。

在前面的例子中筆者多次使用了bash命令,如果在當前shell中執行bash指令後,則會進入乙個新的shell,這個shell就是原來shell的子shell了,不妨你用pstree指令來檢視一下。

pstree這個指令會把linux系統中所有程序通過樹形結構列印出來。限於篇幅筆者沒有全部列出,你可以直接輸入pstree檢視即可。在父shell中設定乙個變數後,進入子shell後該變數是不會生效的,如果想讓這個變數在子shell中生效則要用到export指令,筆者曾經在前面用過。

export其實就是宣告一下這個變數的意思,讓該shell的子shell也知道變數abc的值是123.如果export後面不加任何變數名,則它會宣告所有的變數。

在最後面連同我們自定義的變數都被宣告了。

前面光講如何設定變數,如果想取消某個變數怎麼辦?只要輸入」unset 變數名」即可。

用unset abc後,再echo $abc則不再輸出任何內容。

【系統環境變數與個人環境變數的配置檔案】

上面講了很多系統的變數,那麼在linux系統中,這些變數被存到了**呢,為什麼使用者一登陸shell就自動有了這些變數呢?

/etc/profile :這個檔案預設了幾個重要的變數,例如path, user, logname, mail, inputrc, hostname, histsize, umas等等。

/etc/bashrc :這個檔案主要預設umask以及ps1。這個ps1就是我們在敲命令時,前面那串字元了,例如筆者的linux系統ps1就是 [root@localhost ~]# ,你不妨看一下ps1的值。

\u就是使用者,\h 主機名, \w 則是當前目錄,\$就是那個』#』了,如果是普通使用者則顯示為』$』

除了兩個系統級別的配置檔案外,每個使用者的主目錄下還有幾個這樣的隱藏檔案:

.bash_profile :定義了使用者的個人化路徑與環境變數的檔名稱。每個使用者都可使用該檔案輸入專用於自己使用的shell資訊,當使用者登入時,該檔案僅僅執行一次。

.bashrc :該檔案包含專用於你的shell的bash資訊,當登入時以及每次開啟新的shell時,該該檔案被讀取。

例如你可以將使用者自定義的alias或者自定義變數寫到這個檔案中。

shell指令碼小結

一 輸入 使用者的輸入用 n來表示,n為1 9的自然數,0為指令碼檔名 eg bin bash echo echo echo echo echo 0 echo 1 echo 2 echo 3 二 變數定義 所有變數都是字串,不需要單獨定義,就可以直接賦值。引用變數在名字前加 可以加雙引號包含要引用的...

Shell指令碼程式設計詳解

shell命令列的執行 編寫 修改許可權和執行shell程式的步驟 在shell程式中使用引數和變數 表示式比較 迴圈結構語句和條件結構語句 在shell程式中使用函式和呼叫其他shell程式 shell命令列的書寫規則 對shell命令列基本功能的理解有助於編寫更好的shell程式,在執行shel...

Makefile與shell指令碼區別

在makefile可以呼叫shell指令碼,但是makefile和shell指令碼是不同的。1 shell中所有引用以 打頭的變數其後要加 而在makefile中的變數是以 打頭的後加 例項如下 makefile path data subpath path shell path data subp...