一、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