天天看點

shell-bash之九大特性詳解

一、shell是什麼?

Shell 本身是一個用C語言編寫的程式,它是使用者使用Unix/Linux的橋梁,使用者的大部分工作都是通過Shell完成的。Shell既是一種指令語言,又是一種程式設計語言。作為指令語言,它互動式地解釋和執行使用者輸入的指令;作為程式設計語言,它定義了各種變量和參數,并提供了許多在進階語言中才具有的控制結構,包括循環和分支。

如圖shell是一個應用程式,是使用者管理應用程式的一個接口。

GUI:圖形使用者界面

KDE,GNOME,XFCE

CLI:指令行接口

bash, zsh, fishsh, csh, tcsh, ksh

在大多發行版中常用的為bash

三、bash的特性

bash是弱類型的程式設計語言,不嚴格區分資料類型,意味把所有資料統統當作字元串處理;

字元串類型的資料可不加引号; 

引号有三種類型:', ", `

', ":字元引用

': 強引用,其内部的變量不會被替換; 

":弱引用,其内部的變量會被替換;

`:指令引用

變量引用:${NAME}

擷取目前使用者可用的别名的定義:

定義别名:

生命周期:目前shell程序;

撤消别名:

shell程序會儲存其會話中使用者曾經執行過的指令;指令通過其“曆史檔案”來持久儲存此前執行過的指令;每個使用者都有其自己專用的曆史檔案;

HISTSIZE:shell程序的緩沖區保留的曆史指令的條數;

HISTFILESIZE:指令曆史檔案可儲存的曆史指令的條數;

預設均為1000;       

HISTFILE:目前使用者的指令曆史檔案;

~/.bash_history

檢視指令曆史清單:

指令用法:

history -c:清空指令曆史;

history  -d  OFFSET:删除指定的條目;

-a        将目前緩沖的曆史行追加到曆史檔案中

-n        從曆史檔案中讀取所有未被讀取的行

-r        讀取曆史檔案并将内容追加到曆史清單中

調用指令曆史清單中的指令以重執行之目的:

!#:再一次執行曆史清單中的第#條指令;

!!:再一次執行上一條指令;

!STRING:再一次執行指令曆史清單中最近一個以指定的STRING開頭的指令;

調用上一條指令的最後一個參數:

快捷鍵:ESC, .

Alt+.

!$:給出的字元組合

顯示最近的n條件指令曆史:

history  #

控制指令曆史的記錄方式:

通過HISTCONTROL環境變量進行,其取值:

ignoredups:忽略重複的指令;重複是指連續且相同的令;

ignorespace:以空白字元開頭的指令不記入曆史;

ignoreboth:上述兩者同時生效;

修改變量值的方式:

NAME='VALUE'

Ctrl+a:跳至指令行首;

Ctrl+e:跳至指令行尾;

Ctrl+k:删除光标所在處至尾部的内容;

Ctrl+u:删除行首至光标所在處的内容;

指令補全:

shell程式在接收到使用者執行指令的請求且分析完成之後,最左側字元串将被當作指令去查找;

查找機制:

(1) 查找内部指令;

(2) 查找外部指令:

1、去$PATH變量所指定的各路徑下,自左而右逐個搜尋各目錄下的檔案名;

2、給定的打頭的字元串如果能惟一辨別某指令程式檔案的檔案名,則直接補全;

3、不能惟一辨別,再擊tab可給清單;

4、錯誤:沒有任何指令可被此打頭字元串辨別;

路徑補全:

在給定的起始路徑的上級目錄下,以對應路徑下的打頭字元串來逐一比對上級目标下的每個檔案:

惟一辨別:tab補全;

不能惟一辨別:tab, tab給出清單;

錯誤路徑:沒有響應;

把指令行的給定的特殊符号自動替換為相應字元串的機制;

~: 自動替換為使用者家目錄;

~USERNAME:自動替換為指定使用者的家目錄;

{}:可承載一個以逗号分隔的路徑清單,能夠将其展開為多個獨立路徑;

例如:

/tmp/{a,b,c} /tmp/a /tmp/b /tmp/c

/tmp/{a,b}/z /tmp/a/z /tmp/b/z

指令的正常輸出結果:指令的傳回值;

通過引用來儲存下來或直接調用——”指令引用“

`COMMAND`

$(COMMAND)

指令的執行狀态結果:

成功:0

失敗:1-255

bash用一個特殊變量來儲存最一次執行的指令的狀态結果:

bash中的引用:

'':強引用

"":弱引用

“:指令引用

glob:檔案名通配;快速引用多個檔案;檔案名整體比對度檢測;    

元字元:基于元字元可編寫比對模式(pattern);

*:比對任意長度的任意字元;

p*,  pa*, *p, *p*a

p*:pa, p

?:比對任意單個字元;

p?, p?a, p??

p??: pa, pad, 

[ ]:比對指定集合内的任意單個字元;

[a-z], [A-Z]:不區分字元大小寫;

[a-z0-9]

[[:upper:]]:所有大寫字母;

[[:lower:]]:所有小寫字母;

[[:digit:]]:所有的數字;

[[:alpha:]]:所有字母;

[[:alnum:]]:所有字母和數字;

[[:space:]]:空白字元;

[[:punct:]]:标點符号;

[^ ]:比對指定集合外的任意單個字元;

[^[:alpha:]]

測試:

1、顯示/etc目錄下,以非字母開頭,後面跟了一個字母及其它任意長度任意字元的檔案或目錄; 

2、複制/etc目錄下,是以n開頭,以非數字結尾的檔案或目錄至/tmp/etc目錄下;

3、顯示/usr/share/man目錄下,所有以man開頭,後跟一個數字結尾的檔案或目錄;

4、複制/etc目錄下,是以p,m,r開頭的,且以.conf結尾的檔案或目錄至/tmp/conf.d目錄下;

程式:指令+資料

資料:檔案、變量;

變量:記憶體空間,有名稱,名稱即為變量名,對應的記憶體空間中的資料即為變量的值;

變量指派:NAME=VALUE

=:指派符号;

把VALUE存儲到NAME指向的記憶體空間中;

程式設計語言:

強類型:嚴格區分變量中的資料類型;

弱類型:不區分變量中存儲的資料類型,統一為字元型;

bash:統統預設為字元型資料;變量無需事先聲明;

變量為什麼有類型?

存儲空間、存儲格式、參與的運算、……

類型不同決定對資料的處理方式不同

變量命名:隻能使用字母、數字和下劃線;而且不能以數字開頭;

變量名:見名知義;不能使用程式保留字,例如if、case、then、fi、esac、for、while、until、break、continue等等;

變量引用:${NAME}, $NAME

變量替換:把變量引用符号出現的位置替換為其指向的記憶體空間中的資料;

bash變量種類:

本地變量:作用域為目前shell程序;不包括其子程序;

環境變量:使用域為目前shell程序及其子程序;

局部變量

作用域:生效範圍,也即可引用到的範圍;

位置參數變量:

特殊變量

本地變量:

變量引用:$NAME, ${NAME}

檢視變量:set

撤銷變量:unset NAME

注意:此處非為變量引用,是以不能使用$;

所有的本地變量在shell程序終止時,會被自動撤銷;

環境變量:

變量聲明和指派:

declare -x  NAME[=VALUE]

export  NAME[=VALUE]

引用方式:

${NAME}, $NAME

注意:bash内嵌了許多環境變量,名稱為全大寫字母,例如UID、HOME、PWD、SHELL, PATH, HISTSIZE等等;

環境變量檢視:

export, declare  -x

env,  printenv

撤銷環境變量:

unset  NAME

隻讀變量:常量

(1) declare  -r  NAME

(2) readonly  NAME

不支援重新指派,也不支援撤銷操作;

程式的資料流有三個:

輸入資料流: <–,标準輸入(stdin),鍵盤;

輸出資料流:–>,标準輸出(stdout), 顯示器;

錯誤資料流:–>,錯誤輸出(stderr),顯示器;

fd:file descriptor,檔案描述符;

stdin: 0

stdout: 1

stderr: 2

IO重定向:

輸出重定向:

重定向程式正常執行的結果

COMMAND >  /PATH/TO/SOMEFILE

覆寫重定向:覆寫目标檔案中的原有内容;

COMMAND >> /PATH/TO/SOMEFILE

追加重定向:追加新産生的内容至目标檔案尾部;

shell的一個功能開關:

# set -C

禁止覆寫輸出重定向至已存在的檔案;

注意:此時仍然可以使用“>|”至目标檔案; 

# set +C

關閉上述特性;

錯誤重定向:

重定向錯誤的執行結果;

COMMAND 2>  /PATH/TO/SOMEFILE

錯誤輸出覆寫重定向;

COMMAND 2>> /PATH/TO/SOMEFILE

錯誤輸出追加重定向;

合并标準輸出與錯誤輸出流:

(1) &>, &>>

(2) COMMAND > /PATH/TO/SOMEFILE 2>&1

COMMAND >> /PATH/TO/SOMEFILE 2>&1

特殊輸出目标:/dev/null

位桶:bit bucket

特殊的輸入檔案:/dev/zero

輸入重定向:

COMMAND < /PATH/FROM/SOMEFILE

tr指令:把輸出的資料當中的字元,實作對位轉換,即把資料中的存在于字元集中的字元,統統轉換為字元集2中對應的字元;

tr – translate or delete characters

tr [OPTION]… SET1 [SET2]

(1) tr  SET1  SET2 < /PATH/FROM/SOMEFILE

字元轉換

(2) tr  -d  SET1  < /PATH/FROM/SOMEFILE

COMMAND << :

Here Document

COMMAND << EOF

COMMAND > /PATH/TO/SOMEFILE << EOF

COMMAND1 | COMMAND2 | COMMAND3 | …

練習1:把/etc/passwd檔案最後三行資訊中所有小寫字元改為大寫後輸出;

練習2:取出/etc/fstab的第6行;

練習3:取出/etc目錄下所有以p開頭的檔案或目錄,隻顯示前5個;

tee指令:

tee – read from standard input and write to standard output and files

tee [OPTION]… [FILE]…

-a:使用追加輸出,而非覆寫;

COMMAND | tee /PATH/TO/SOMEFILE

繼續閱讀