linux学习之shell基础篇
1、shell簡介 ?
?? ??
shell是用戶和Linux內(nèi)核之間的接口程序,如果把Linux內(nèi)核想象成一個球體的中心,shell就是圍繞內(nèi)核的外層。當從shell或其他程序向Linux傳遞命令時,內(nèi)核會做出相應的反應。
2、shell的工作原理
? 系統(tǒng)初啟后,核心為每個終端用戶建立一個進程去執(zhí)行Shell解釋程序。它的執(zhí)行過程基本上按如下步驟:?
? (1)讀取用戶由鍵盤輸入的命令行。?
? (2)分析命令,以命令名作為文件名,并將其它參數(shù)改造為系統(tǒng)調(diào)用execve( )內(nèi)部處理所要求的形 ? ? ? ?式。
? (3)終端進程調(diào)用fork( )建立一個子進程。?
? (4)終端進程本身用系統(tǒng)調(diào)用wait4()來等待子進程完成(如果是后臺命令,則不等待)。當子進程運 ? ? 行時調(diào)用execve(),子進程根據(jù)文件名(即命令名)到目錄中查找有關(guān)文件(這是命令解釋程序構(gòu) ? ? 成的文件),將它調(diào)入內(nèi)存,執(zhí)行這個程序(解釋這條命令)。?
? (5)如果命令末尾有&號(后臺命令符號),則終端進程不用系統(tǒng)調(diào)用wait4()等待,立即發(fā)提示符,讓 ? ? ?用戶輸入下一個命令,轉(zhuǎn)⑴。如果命令末尾沒有&號,則終端進程要一直等待,當子進程(即運行 ? ? ?命令的進程)完成處理后終止,向父進程(終端進程)報告,此時終端進程醒來,在做必要的判別 ? ? ?等工作后,終端進程發(fā)提示符,讓用戶輸入新的命令
3、程序
程序就是指令加數(shù)據(jù),起功能就是通過指令去加工指定的數(shù)據(jù),并輸出結(jié)果;
程序編寫分為兩種:
? ? 面向過程:以指令為中心
面向?qū)ο?#xff1a;以數(shù)據(jù)為中心
bash屬于面向?qū)ο蟮木幊陶Z言;bash有三種控制執(zhí)行方式
? ?順序執(zhí)行:逐個執(zhí)行
選擇執(zhí)行:只執(zhí)行其中一個分支
循環(huán)執(zhí)行:一段代碼要執(zhí)行0,1或多遍
4、程序執(zhí)行的分類
? 程序按照編譯方式來可以分為兩類
? ? ? ? 編譯執(zhí)行:預處理-->編譯-->匯編-->鏈接;事先完成,結(jié)果:二進制程序文件
如是用C, C++等語言開發(fā)的程序
解釋執(zhí)行:由解釋器全程參與運行過程,每次讀取一行,運行一行;
Python:編程庫
程序控制結(jié)構(gòu),調(diào)用編程庫完成程序編寫;
庫文件:功能模塊,在編程中可調(diào)用;通過其API;
Bash:編程
程序控制結(jié)構(gòu),調(diào)用機器上命令程序文件進行程序編寫;
外部命令:各應用程序提供;
5、變量
? ?變量就是內(nèi)存中存放可變量的空間;
? ?bash的變量分為:
? ? 環(huán)境變量:有效范圍是當前shell進程及其子進程
? ? 本地變量:當前進程
? ? 局部變量:某個函數(shù)的執(zhí)行過程
? ? 位置參數(shù)變量:在腳本中引用傳遞給腳本的參數(shù);在函數(shù)中引用傳遞給函數(shù)的參數(shù);
? ? 特殊變量:$?, $*, $@, $#, $$
? ?
? ?變量的類型(bash默認是字符型)
? ? 數(shù)值型
? 整數(shù)
? 浮點數(shù)
字符型
? ASCII
如;120?
數(shù)值型則為120
字符型則為1、2、0
bash的變量是不嚴格區(qū)分類型,也不必事先聲明
6、本地變量:
name=value
? ?name: 變量名
? ??=:賦值符號
? ??value:值
變量名:只能包含數(shù)字、字母和下劃線;且不能以數(shù)字開頭;
引用變量:${name}, $name
? ? ? ? 引用:
弱引用: "", 其內(nèi)部的變量引用會被替換為變量值;
強引用:'',其變量的變量引用會保持原有字符;
命令引用:`COMMAND`, $(COMMAND),引用命令的執(zhí)行結(jié)果;
聲明為整型:
? ? ? ? ? ? ? ?declare -i name[=value]
let name=value
查看所有變量:set
生命周期:
創(chuàng)建
銷毀:
自動銷毀:shell進程終止;
手動銷毀:unset name
7、環(huán)境變量:
被“導出”的本地變量
export name[=value]
declare -x name[=value]
查看所有環(huán)境變量:env, printenv, export
? ?銷毀:
unset name
8、腳本:文本文件
運行腳本:事實上是運行一個bash進程,此進程負責從腳本文件中讀取一個執(zhí)行邏輯,而后由bash進程負責解析并運行此邏輯;
啟動腳本:
(1) # bash /PATH/TO/SCRIPT_FILE
(2) 一個執(zhí)行權(quán)限,?
# ./PATH/TO/SCRIPT_FILE?
shebang:
#!/bin/bash
第一行:頂格給出shebang
注釋行:#
bash的常用選項:
-n: 檢查腳本中的語法錯誤;
-x:調(diào)試執(zhí)行腳本;
9、命令狀態(tài)結(jié)果:
bash進程用于追蹤執(zhí)行的命令成功與否的狀態(tài):
0: 成功
1-255:失敗
特殊變量:
$?:上一條命令的執(zhí)行狀態(tài)結(jié)果;
布爾型:
“真”:成功
“假”:失敗
自定義腳本的狀態(tài)結(jié)果:
exit [n]
注意:腳本中任何位置執(zhí)行了exit命令即會終止當前shell進程;
10、條件測試:
界定程序執(zhí)行環(huán)境;
(1) 根據(jù)運行的命令的狀態(tài)結(jié)果;
(2) 測試表達式
test EXPRESSION
[ EXPRESSION ]
` EXPRESSION `
整數(shù)測試:隱含著做數(shù)值大小比較,所以不要給變量引用加引用;
$A -gt $B:是否大于;是則為“真”,否則為“假”;
$A -ge $B: 是否大于等于;
$A -lt $B:是否小于;
$A -le $B: 是否小于等于;
$A -eq $B: 是否等于;
$A -ne $B:是否不等于;
[root@pizi?~]#?cat?test.sh #!/bin/bash declare?-i?x=10 declare?-i?y=100 echo?"x=$x" echo?"y=$y" echo?"判斷上面兩個數(shù)值得大小,是則輸出0,否則輸出非0"echo?"$x?-gt?$y:x是否大于y" test?$x?-gt?$y;echo?$?echo?"$x?-ge?$y:x是否大于等于y" test?$x?-ge?$y;echo?$?echo?"$x?-lt?$y:x是否小于y" test?$x?-lt?$y;echo?$?echo?"$x?-le?$y:x是否小于等于y" test?$x?-le?$y;echo?$?echo?"$x?-eq?$y;x是否等于y" test?$x?-eq?$y;echo?$?echo?"$x?-ne?$y;x是否不等于y" test?$x?-ne?$y;echo?$? [root@pizi?~]#[root@pizi?~]#?bash?test.sh x=10 y=100 判斷上面兩個數(shù)值得大小,是則輸出0,否則輸出非0 10?-gt?100:x是否大于y 1 10?-ge?100:x是否大于等于y 1 10?-lt?100:x是否小于y 0 10?-le?100:x是否小于等于y 0 10?-eq?100;x是否等于y 1 10?-ne?100;x是否不等于y 0 [root@pizi?~]#字符串測試:ASCII數(shù)值越大,字符比較時其值越大;
"$A" > "$B":是否大于;
"$A" < "$B":是否小于;
"$A" == "$B":是否等于;
"$A" != "$B":是否不等于;
-z "$A":是否為空;空則為“真”,否則為“假”
-n "$A":是否不空;不空則“真”,空則為“假”
注意:應該使用` EXPRESSION `
[root@pizi?~]#?cat?test.sh? #!/bin/bash A=hello B=world echo?"A?is?$A" echo?"B?is?$B" echo?"測試字符串A,B,是則為“真”(0),否則為“假”(非零);"echo?""$A"?>?"$B":是否大于;" [[?"$A"?>?"$B"?]];echo?$?echo?""$A"?<?"$B":是否小于;" [[?"$A"?<?"$B"?]];echo?$?echo?""$A"?==?"$B":是否等于;" [[?"$A"?==?"$B"?]];echo?$?echo?""$A"?!=?"$B":是否不等于;" [[?"$A"?!=?"$B"?]];echo?$?echo?"-z?"$A":是否為空;空則為“真”,否則為“假”" [[?-z?"$A"?]];echo?$?echo?"-n?"$A":是否不空;不空則“真”,空則為“假”" [[?-n?"$A"?]];echo?$?[root@pizi?~]#?bash?test.sh??? A?is?hello B?is?world 測試字符串A,B,是則為“真”(0),否則為“假”(非零); hello?>?world:是否大于; 1 hello?<?world:是否小于; 0 hello?==?world:是否等于; 1 hello?!=?world:是否不等于; 0 -z?hello:是否為空;空則為“真”,否則為“假” 1 -n?hello:是否不空;不空則“真”,空則為“假” 0文件測試:測試文件的存在性以及屬性;
-e $file: 是否存在;存在則為“真”,否則為“假”;
-a $file: 同上;
-f $file:文件是否存在且為普通文件;
-d $file:文件是否存在且為目錄;
-h $file:是否存在且為符號鏈接文件;
-L $file: 同上
-b $file:是否存在且為塊設(shè)備文件;
-c $file:是否存在且為字符設(shè)備文件;
-S $file:是否存在且為套接字文件;
-p $file: 是否存在且為管道文件;
-r $file: 當前用戶對文件是否擁有讀權(quán)限;
-w $file:當前用戶對文件是否擁有寫權(quán)限;
-x $file:當前用戶對文件是否擁有執(zhí)行權(quán)限;
-u $file:文件是否擁有SUID權(quán)限;
-g $file:文件是否擁有SGID權(quán)限;
-k $file:文件是否擁有sticky權(quán)限;
-O $file: 當前用戶是否為指定文件的屬主;
-G $file: 當前用戶是否為指定文件的屬組;
雙目操作符:
$file1 -nt $file2: file1是否新于file2, file1的最近一次的修改時間戳是否晚于file2的;
$file1 -ot $file2: file1是否舊于file2, file1的最近一次的修改時間戳是否早于file2的;?
$file1 -ef $file2:file1與file2是否指向了同一個inode;測試二者是否為同一個文件的硬鏈接;
特殊設(shè)備:
/dev/null: 空,bit buckets,吞下所有數(shù)據(jù),并直接丟棄;
/dev/zero:吐出一堆0;
轉(zhuǎn)載于:https://blog.51cto.com/pizimsn/1697671
《新程序員》:云原生和全面數(shù)字化實踐50位技術(shù)專家共同創(chuàng)作,文字、視頻、音頻交互閱讀總結(jié)
以上是生活随笔為你收集整理的linux学习之shell基础篇的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。