1. 程式人生 > 其它 >【轉】linux的基本操作(shell 指令碼的基礎知識)

【轉】linux的基本操作(shell 指令碼的基礎知識)

轉載https://www.cnblogs.com/zhang-jun-jie/p/9266844.html

shell 指令碼的基礎知識

日常的linux系統管理工作中必不可少的就是shell指令碼,如果不會寫shell指令碼,那麼你就不算一個合格的管理員。目前很多單位在招聘linux系統管理員時,shell指令碼的編寫是必考的專案。有的單位甚至用shell指令碼的編寫能力來衡量這個linux系統管理員的經驗是否豐富。筆者講這些的目的只有一個,那就是讓你認真對待shell指令碼,從一開始就要把基礎知識掌握牢固,然後要不斷的練習,只要你shell指令碼寫的好,相信你的linux求職路就會輕鬆的多。筆者在這一章中並不會多麼詳細的介紹shell指令碼,而只是帶你進入shell指令碼的世界,如果你很感興趣那麼請到網上下載相關的資料或者到書店購買相關書籍吧。

在學習shell指令碼之前,需要你瞭解很多關於shell的知識,這些知識是編寫shell指令碼的基礎,所以希望你能夠熟練的掌握。

什麼是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或者自定義變數寫到這個檔案中。

.bash_history:記錄命令歷史用的。

.bash_logout:當退出shell時,會執行該檔案。可以把一些清理的工作放到這個檔案中。

linux shell中的特殊符號

你在學習linux的過程中,也許你已經接觸過某個特殊符號,例如”*”,它是一個通配符號,代表零個或多個字元或數字。下面筆者就說一說常用到的特殊字元

1. *:代表零個或多個字元或數字。

test後面可以沒有任何字元,也可以有多個字元,總之有或沒有都能匹配出來。

2. ?:只代表一個任意的字元

不管是數字還是字母,只要是一個都能匹配出來。

3. #:這個符號在linux中表示註釋說明的意思,即”#”後面的內容linux忽略掉。

在命令的開頭或者中間插入”#”,linux都會忽略掉的。這個符號在shell指令碼中用的很多。

4. \:脫意字元,將後面的特殊符號(例如”*”)還原為普通字元。

5. |:管道符,前面多次說過,它的作用在於將符號前面命令的結果丟給符號後面的命令。這裡提到的後面的命令,並不是所有的命令都可以的,一般針對文件操作的命令比較常用,例如cat, less, head, tail, grep, cut, sort, wc, uniq, tee, tr, split, sed, awk等等,其中grep, sed, awk為正則表示式必須掌握的工具,在後續內容中詳細介紹。

6. $:除了用於變數前面的識別符號外,還有一個妙用,就是和’!’結合起來使用。

‘!$’表示上條命中中最後一個變數(也許稱為變數不合適,總之就是上條命令中最後出現的那個東西)例如上邊命令最後是test.txt那麼在當前命令下輸入!$則代表test.txt。

1grep:過濾一個或多個字元,將會在後續內容中詳細介紹其用法。

2) cut:擷取某一個欄位

語法:cut -d “分隔字元” [-cf] n這裡的n是數字

-d:後面跟分隔字元,分隔字元要用雙引號括起來

-c:後面接的是第幾個字元

-f:後面接的是第幾個區塊

-d後面跟分隔字元,這裡使用冒號作為分割字元,-f 1就是擷取第一段,-f和1之間的空格可有可無。

-c後面可以是1個數字n,也可以是一個區間n1-n2,還可以是多個數字n1,n2,n3

3) sort:用做排序

語法:sort [-t分隔符] [-kn1,n2] [-nru]這裡的n1 < n2

-t分隔符:作用跟cut的-d一個意思

-n:使用純數字排序

-r:反向排序

-u:去重複

-kn1,n2:由n1區間排序到n2區間,可以只寫-kn1,即對n1欄位排序

4) wc:統計文件的行數、字元數、詞數,常用的選項為:

-l:統計行數

-m:統計字元數

-w:統計詞數

5uniq:去重複的行,筆者常用的選項只有一個:

-c:統計重複的行數,並把行數寫在前面

有一點需要注意,在進行uniq之前,需要先用sort排序然後才能uniq,否則你將得不到你想要的,筆者上面的試驗當中已經是排序過所以省略掉那步了。

6tee:後跟檔名,類似與重定向”>”,但是比重定向多了一個功能,在把檔案寫入後面所跟的檔案中的同時,還顯示在螢幕上。

7tr:替換字元,常用來處理文件中出現的特殊符號,如DOS文件中出現的^M符號。常用的選項有兩個:

-d:刪除某個字元,-d後面跟要刪除的字元

-s:把重複的字元去掉

最常用的就是把小寫變大寫:tr ‘[a-z]’ ‘[A-Z]’

當然替換一個字元也是完全可以的。

不過替換、刪除以及去重複都是針對一個字元來講的,有一定侷限性。如果是針對一個字串就不再管用了,所以筆者建議只是簡單瞭解這個tr即可,以後你還會學到更多可以實現針對字串操作的工具。

8split:切割文件,常用選項:

-b:依據大小來分割文件,單位為byte

格式如上例,後面的passwd為分割後文件名的字首,分割後的檔名為passwdaa, passwdab, passwdac …

-l:依據行數來分割文件

6.分號。平時我們都是在一行中敲一個命令,然後回車就運行了,那麼想在一行中執行兩個或兩個以上的命令如何呢?則需要在命令之間加一個”;”了。

7. ~:使用者的家目錄,如果是root則是/root,普通使用者則是/home/username

8. &:如果想把一條命令放到後臺執行的話,則需要加上這個符號。通常用於命令執行時間非常長的情況。

使用jobs可以檢視當前shell中後臺執行的任務。用fg可以調到前臺執行。這裡的sleep命令就是休眠的意思,後面跟數字,單位為秒,常用語迴圈的shell指令碼中。

此時你按一下CTRL +z使之暫停,然後再輸入bg可以再次進入後臺執行。

如果是多工情況下,想要把任務調到前臺執行的話,fg後面跟任務號,任務號可以使用jobs命令得到。

9.>, >>, 2>, 2>>:前面講過重定向符號>以及>> 分別表示取代和追加的意思,然後還有兩個符號就是這裡的2>和2>> 分別表示錯誤重定向和錯誤追加重定向,當我們執行一個命令報錯時,報錯資訊會輸出到當前的螢幕,如果想重定向到一個文本里,則要用2>或者2>>。

10. [ ]:中括號,中間為字元組合,代表中間字元中的任意一個

11. &&||

在上面剛剛提到了分號,用於多條命令間的分隔符。另外還有兩個可以用於多條命令中間的特殊符號,那就是“&&”和”||”。下面筆者把這幾種情況全列出:

1) command1 ; command2

2) command1 && command2

3) command1 || command2

使用”;”時,不管command1是否執行成功都會執行command2;使用”&&”時,只有command1執行成功後,command2才會執行,否則command2不執行;使用”||”時,command1執行成功後command2不執行,否則去執行command2,總之command1和command2總有一條命令會執行。

轉載https://www.cnblogs.com/zhang-jun-jie/p/9266844.html

【轉】Linux shell ${}簡單用法

轉載:https://www.cnblogs.com/xudong-bupt/p/3567096.html

為了完整起見,我這裡再用一些例子加以說明 ${ } 的一些特異功能:
假設我們定義了一個變數為:
file=/dir1/dir2/dir3/my.file.txt
我們可以用 ${ } 分別替換獲得不同的值:
${file#*/}:拿掉第一條 / 及其左邊的字串:dir1/dir2/dir3/my.file.txt
${file##*/}:拿掉最後一條 / 及其左邊的字串:my.file.txt
${file#*.}:拿掉第一個 . 及其左邊的字串:file.txt
${file##*.}:拿掉最後一個 . 及其左邊的字串:txt
${file%/*}:拿掉最後條 / 及其右邊的字串:/dir1/dir2/dir3
${file%%/*}:拿掉第一條 / 及其右邊的字串:(空值)
${file%.*}:拿掉最後一個 . 及其右邊的字串:/dir1/dir2/dir3/my.file
${file%%.*}:拿掉第一個 . 及其右邊的字串:/dir1/dir2/dir3/my

記憶的方法為:

# 是去掉左邊(在鑑盤上 # 在 $ 之左邊)

% 是去掉右邊(在鑑盤上 % 在 $ 之右邊)

單一符號是最小匹配﹔兩個符號是最大匹配。


${file:0:5}:提取最左邊的 5 個位元組:/dir1
${file:5:5}:提取第 5 個位元組右邊的連續 5 個位元組:/dir2
我們也可以對變數值裡的字串作替換:
${file/dir/path}:將第一個 dir 提換為 path:/path1/dir2/dir3/my.file.txt
${file//dir/path}:將全部 dir 提換為 path:/path1/path2/path3/my

轉載:https://www.cnblogs.com/xudong-bupt/p/3567096.html