前言
大家好,這里是浩道linux,主要給大家分享linux、python、網(wǎng)絡(luò)通信相關(guān)的IT知識平臺。
今天浩道跟大家分享關(guān)于shell編程相關(guān)的硬核干貨,通過本文你將吃透shell編寫相關(guān)工具及基本法則。讓你編寫shell腳本如魚得水!
文章來源:資源整理綜合自網(wǎng)絡(luò)
1. 文件處理工具
1.1 grep工具
行過濾
grep用于根據(jù)關(guān)鍵字進行行過濾 grepoptions'keys'filename OPTIONS: -i:不區(qū)分大小寫 -v:查找不包含指定內(nèi)容的行,反向選擇 -w:按單詞搜索 -o:打印匹配關(guān)鍵字 -c:統(tǒng)計匹配到的次數(shù) -n:顯示行號 -r:逐層遍歷目錄查找 -A:顯示匹配行及后面多少行 -B:顯示匹配行及前面多少行 -C:顯示匹配行前后多少行 -l:只列出匹配的文件名 -L:列出不匹配的文件名 -e:使用正則匹配 -E:使用擴展正則匹配 ^key:以關(guān)鍵字開頭 key$:以關(guān)鍵字結(jié)尾 ^$:匹配空行 --color=auto :可以將找到的關(guān)鍵詞部分加上顏色的顯示 臨時設(shè)置: #aliasgrep='grep--color=auto'//只針對當前終端和當前用戶生效 永久設(shè)置: 1)全局(針對所有用戶生效) vim/etc/bashrc aliasgrep='grep--color=auto' source/etc/bashrc 2)局部(針對具體的某個用戶) vim~/.bashrc aliasgrep='grep--color=auto' source~/.bashrc 示例: #grep-irootpasswd忽略大小寫匹配包含root的行 #grep-wftppasswd精確匹配ftp單詞 #grep-whellopasswd精確匹配hello單詞;自己添加包含hello的行到文件中 #grep-woftppasswd打印匹配到的關(guān)鍵字ftp #grep-nrootpasswd打印匹配到root關(guān)鍵字的行好 #grep-nirootpasswd忽略大小寫匹配統(tǒng)計包含關(guān)鍵字root的行 #grep-nicrootpasswd忽略大小寫匹配統(tǒng)計包含關(guān)鍵字root的行數(shù) #grep-i^rootpasswd忽略大小寫匹配以root開頭的行 #grepbash$passwd匹配以bash結(jié)尾的行 #grep-n^$passwd匹配空行并打印行號 #grep^#/etc/vsftpd/vsftpd.conf匹配以#號開頭的行 #grep-v^#/etc/vsftpd/vsftpd.conf匹配不以#號開頭的行 #grep-A5mailpasswd匹配包含mail關(guān)鍵字及其后5行 #grep-B5mailpasswd匹配包含mail關(guān)鍵字及其前5行 #grep-C5mailpasswd匹配包含mail關(guān)鍵字及其前后5行
1.2 cut工具
列截取
cut用于列截取 -c:以字符為單位進行分割。 -d:自定義分隔符,默認為制表符。 -f:與-d一起使用,指定顯示哪個區(qū)域。 #cut-d:-f11.txt以:冒號分割,截取第1列內(nèi)容 #cut-d:-f1,6,71.txt以:冒號分割,截取第1,6,7列內(nèi)容 #cut-c41.txt截取文件中每行第4個字符 #cut-c1-41.txt截取文件中每行的1-4個字符 #cut-c4-101.txt #cut-c5-1.txt從第5個字符開始截取后面所有字符 課堂練習: 用小工具列出你當系統(tǒng)的運行級別。5/3
1.3 sort工具
排序
sort:將文件的每一行作為一個單位,從首字符向后,依次按ASCII碼值進行比較,最后將他們按升序輸出。 -u :去除重復行 -r :降序排列,默認是升序 -o:將排序結(jié)果輸出到文件中類似重定向符號> -n :以數(shù)字排序,默認是按字符排序 -t :分隔符 -k :第N列 -b :忽略前導空格。 -R :隨機排序,每次運行的結(jié)果均不同。 示例: #sort-n-t:-k31.txt按照用戶的uid進行升序排列 #sort-nr-t:-k31.txt按照用戶的uid進行降序排列 #sort-n2.txt按照數(shù)字排序 #sort-nu2.txt按照數(shù)字排序并且去重 #sort-nr2.txt #sort-nru2.txt #sort-nru2.txt #sort-n2.txt-o3.txt按照數(shù)字排序并將結(jié)果重定向到文件 #sort-R2.txt #sort-u2.txt
1.4 uniq工具
去除連續(xù)的重復行
uniq:去除連續(xù)重復行 -i:忽略大小寫 -c:統(tǒng)計重復行次數(shù) -d:只顯示重復行 #uniq2.txt #uniq-d2.txt #uniq-dc2.txt
1.5 tee工具
tee工具從標準輸入讀取并寫入標準輸出和文件,即:雙向覆蓋重定向<屏幕輸出|文本輸入> -a雙向追加重定向 #echohelloworld #echohelloworld|teefile1 #catfile1 #echo999|tee-afile1 #catfile1
1.6 paste工具
paste工具用于合并文件行 -d:自定義間隔符,默認是tab -s:串行處理,非并行 [root@servershell01]#cata.txt hello [root@servershell01]#catb.txt helloworld 888 999 [root@servershell01]#pastea.txtb.txt hellohelloworld 888 999 [root@servershell01]#pasteb.txta.txt helloworldhello 888 999 [root@servershell01]#paste-d'@'b.txta.txt helloworld@hello 888@ 999@ [root@servershell01]#paste-sb.txta.txt helloworld888999 hello
1.7 tr工具
==字符轉(zhuǎn)換:替換,刪除==
tr用來從標準輸入中通過替換或刪除操作進行字符轉(zhuǎn)換;主要用于刪除文件中控制字符或進行字符轉(zhuǎn)換。 使用tr時要轉(zhuǎn)換兩個字符串:字符串1用于查詢,字符串2用于處理各種轉(zhuǎn)換。 語法: commands|tr'string1''string2' tr'string1''string2'
小試牛刀
使用小工具分別截取當前主機IP;截取NETMASK;截取廣播地址;截取MAC地址
[root@servershell01]#ifconfigeth0|grep'Bcast'|tr-d'[a-zA-Z]'|cut-d:-f2,3,4 10.1.1.1255.255.255.0 [root@servershell01]#ifconfigeth0|grep'Bcast'|tr-d'[a-zA-Z]'|cut-d:-f2,3,4|tr':'' ' 10.1.1.1 10.1.1.255 255.255.255.0 [root@servershell01]#ifconfigeth0|grep'HWaddr'|cut-d:-f2-|cut-d''-f4 0029AE:54 #ifconfigeth1|grepBcast|cut-d:-f2|cut-d''-f1 #ifconfigeth1|grepBcast|cut-d:-f2|tr-d'[a-zA-Z]' #ifconfigeth1|grepBcast|tr-d'[:a-zA-Z]'|tr'''@'|tr-s'@'|tr'@'' '|grep-v^$ #ifconfigeth0|grep'Bcast'|tr-d[]|tr'[:]'' '|grep-v^$ #ifconfigeth1|grepHWaddr|cut-d''-f11 #ifconfigeth0|grepHWaddr|tr-s''|cut-d''-f5 #ifconfigeth1|grepHWaddr|tr-s''|cut-d''-f5
將系統(tǒng)中所有普通用戶的用戶名、密碼和默認shell保存到一個文件中,要求用戶名密碼和默認shell之間用tab鍵分割
[root@servershell01]#grep'bash$'passwd|grep-v'^root'|cut-d:-f1,2,7|tr':'' ' stu1x/bin/bash codex/bin/bash kefux/bin/bash kefu1x/bin/bash kefu2x/bin/bash user01x/bin/bash stu2x/bin/bash [root@servershell01]#grepbash$passwd|grep-viE'root|mysql'|cut-d:-f1,2,7|tr':'' '|teea.txt 注釋: -E匹配擴展正則表達式,|代表或者,是一個擴展正則
2. 編程語言分類
編譯型語言:
==程序在執(zhí)行之前需要一個專門的編譯過程==,把程序編譯成為機器語言文件,運行時不需要重新翻譯,直接使用編譯的結(jié)果就行了。程序執(zhí)行效率高,依賴編譯器,跨平臺性差些。如C、C++
解釋型語言:
程序不需要編譯,程序在運行時由==解釋器==翻譯成機器語言,每執(zhí)行一次都要翻譯一次。因此效率比較低。比如Python/JavaScript/ Perl /ruby/Shell等都是解釋型語言。
/語言分類
總結(jié):
編譯型語言比解釋型語言==速度較快==,但是不如解釋型語言==跨平臺性好==。如果做底層開發(fā)或者大型應(yīng)用程序或者操作系開發(fā)一==般都用編譯型語言==;如果是一些服務(wù)器腳本及一些輔助的接口,對速度要求不高、對各個平臺的==兼容性有要求==的話則一般都用==解釋型語言==。
3. shell介紹
00_shell介紹
總結(jié):
==shell就是人機交互的一個橋梁==
shell的種類
[root@MissHou~]#cat/etc/shells /bin/sh#是bashshell的一個快捷方式 /bin/bash#bashshell是大多數(shù)Linux默認的shell,包含的功能幾乎可以涵蓋shell所有的功能 /sbin/nologin#表示非交互,不能登錄操作系統(tǒng) /bin/dash#小巧,高效,功能相比少一些 /bin/tcsh#是csh的增強版,完全兼容csh /bin/csh#具有C語言風格的一種shell,具有許多特性,但也有一些缺陷
用戶在終端(終端就是bash的接口)輸入命令
|
bash //bash就是shell的一種類型(bash shell)
|
kernel
|
物理硬件等4. shell腳本
什么是shell腳本?
一句話概括
簡單來說就是將需要執(zhí)行的命令保存到文本中,==按照順序執(zhí)行==。它是解釋型的,意味著不需要編譯。
準確敘述
若干命令 + 腳本的基本格式 + 腳本特定語法 + 思想= shell腳本
什么時候用到腳本?
重復化、復雜化的工作,通過把工作的命令寫成腳本,以后僅僅需要執(zhí)行腳本就能完成這些工作。
①自動化分析處理
②自動化備份
③自動化批量部署安裝
④等等…
如何學習shell腳本?
盡可能記憶更多的命令
掌握腳本的標準的格式(指定魔法字節(jié)、使用標準的執(zhí)行方式運行腳本)
必須==熟悉掌握==腳本的基本語法(重點)
腳本的基本寫法:
#!/bin/bash //腳本第一行,#!魔法字符,指定腳本代碼執(zhí)行的程序。即它告訴系統(tǒng)這個腳本需要什么解釋器來執(zhí)行,也就是使用哪一種Shell //以下內(nèi)容是對腳本的基本信息的描述 #Name:名字 #Desc:描述describe #Path:存放路徑 #Usage:用法 #Update:更新時間 //下面就是腳本的具體內(nèi)容 commands ...
腳本執(zhí)行方法:
標準腳本執(zhí)行方法(建議):(魔法字節(jié)指定的程序會生效)
[root@MissHoushell01]#cat1.sh #!/bin/bash #xxxx #xxx #xxx hostname date [root@MissHoushell01]#chmod+x1.sh [root@MissHoushell01]#ll total4 -rwxr-xr-x1rootroot42Jul2214:401.sh [root@MissHoushell01]#/shell/shell01/1.sh MissHou.itcast.cc SunJul221400CST2018 [root@MissHoushell01]#./1.sh MissHou.itcast.cc SunJul221430CST2018
非標準的執(zhí)行方法(不建議):(魔法字節(jié)指定的程序不會運作)
~~~shell
[root@MissHou shell01]# bash 1.sh
MissHou.itcast.cc
Sun Jul 22 1451 CST 2018
[root@MissHou shell01]# sh 1.sh
MissHou.itcast.cc
Sun Jul 22 1401 CST 2018
[root@MissHou shell01]#
[root@MissHou shell01]# bash -x 1.shhostname
MissHou.itcast.ccdate
Sun Jul 22 1420 CST 2018-x:一般用于排錯,查看腳本的執(zhí)行過程
-n:用來查看腳本的語法是否有問題注意:如果腳本沒有加可執(zhí)行權(quán)限,不能使用標準的執(zhí)行方法執(zhí)行,bash 1.sh
其他:
[root@server shell01]# source 2.sh
server
Thu Nov 22 1550 CST 2018
[root@server shell01]# . 2.sh
server
Thu Nov 22 1507 CST 2018source 和 . 表示讀取文件,執(zhí)行文件里的命令
~~~5. bash基本特性
5.1 命令和文件自動補全
Tab只能補全命令和文件 (RHEL6/Centos6)
5.2 常見的快捷鍵
^c終止前臺運行的程序 ^z將前臺運行的程序掛起到后臺 ^d退出等價exit ^l清屏 ^a|home光標移到命令行的最前端 ^e|end光標移到命令行的后端 ^u刪除光標前所有字符 ^k刪除光標后所有字符 ^r搜索歷史命令
5.3 常用的通配符(重點)
*:匹配0或多個任意字符 ?:匹配任意單個字符 [list]:匹配[list]中的任意單個字符 [!list]:匹配除list中的任意單個字符 {string1,string2,...}:匹配string1,string2或更多字符串 舉例: touchfile{1..3} touchfile{1..13}.jpg #lsfile* #ls*.jpg #llfile? #llfile?.jpg #llfile??.jpg #llfile1?.jpg #llfile?.jpg #llfile[1023].jpg #llfile[0-13].jpg #llfile1[0-9].jpg #llfile[0-9].jpg #llfile?[1-13].jpg #llfile[1,2,3,10,11,12].jpg #llfile1{11,10,1,2,3}.jpg #llfile{1..10}.jpg #llfile{1...10}.jpg
5.4 bash中的引號(重點)
雙引號"" :會把引號的內(nèi)容當成整體來看待,允許通過符號引用其他變量值
[root@serverdir1]#echo"$(hostname)" server [root@serverdir1]#echo'$(hostname)' $(hostname) [root@serverdir1]#echo"helloworld" helloworld [root@serverdir1]#echo'helloworld' helloworld [root@serverdir1]#echo$(date+%F) 2018-11-22 [root@serverdir1]#echo`echo$(date+%F)` 2018-11-22 [root@serverdir1]#echo`date+%F` 2018-11-22 [root@serverdir1]#echo`echo`date+%F`` date+%F [root@serverdir1]#echo$(echo`date+%F`) 2018-11-22
變量的定義
1. 變量的分類
本地變量:當前用戶自定義的變量。當前進程中有效,其他進程及當前進程的子進程無效。
環(huán)境變量:當前進程有效,并且能夠被子進程調(diào)用。
查看當前用戶的環(huán)境變量 env
查詢當前用戶的所有變量(臨時變量與環(huán)境變量) **set **
**export //將當前變量變成環(huán)境變量 **
[root@MissHoutmp]#exportA=hello//臨時將一個本地變量(臨時變量)變成環(huán)境變量 [root@MissHoutmp]#env|grep^A A=hello 永久生效: vim/etc/profile或者~/.bashrc exportA=hello 或者 A=hello exportA 說明:系統(tǒng)中有一個變量PATH,環(huán)境變量 exportPATH=/usr/local/mysql/bin:$PATH
全局變量:全局所有的用戶和程序都能調(diào)用,且繼承,新建的用戶也默認能調(diào)用.
$HOME/.bashrc當前用戶的bash信息(aliase、umask等) $HOME/.bash_profile當前用戶的環(huán)境變量() oracle——>oracle用戶——>$oracle/.bash_profile——>exporthome_install=/u01/app/xxx $HOME/.bash_logout每個用戶退出當前shell時最后讀取的文件 /etc/bashrc使用bashshell用戶全局變量 grep--color=auto umask /etc/profile系統(tǒng)和每個用戶的環(huán)境變量信息 mycat_home=/usr/local/mycat/bin exportmycat_home 執(zhí)行mycat命令 #mycat $mycat 用戶登錄系統(tǒng)讀取相關(guān)文件的順序: /etc/profile——>$HOME/.bash_profile——>$HOME/.bashrc——>/etc/bashrc——>$HOME/.bash_logout source/etc/bashrc
系統(tǒng)變量(內(nèi)置bash中變量):shell本身已經(jīng)固定好了它的名字和作用.
$?:上一條命令執(zhí)行后返回的狀態(tài),當返回狀態(tài)值為0時表示執(zhí)行正常,非0值表示執(zhí)行異?;虺鲥e 若退出狀態(tài)值為0,表示命令運行成功 若退出狀態(tài)值為127,表示commandnotfound 若退出狀態(tài)值為126,表示找到了該命令但無法執(zhí)行(權(quán)限不夠) 若退出狀態(tài)值為1&2,表示沒有那個文件或目錄 $$:當前所在進程的進程號 echo $$ eg:kill -9 `echo $$`= exit 退出當前會話 $!:后臺運行的最后一個進程號(當前終端)# gedit & !$調(diào)用最后一條命令歷史中的參數(shù) !!調(diào)用最后一條命令歷史 $#:腳本后面接的參數(shù)的個數(shù) $*:腳本后面所有參數(shù),參數(shù)當成一個整體輸出,每一個變量參數(shù)之間以空格隔開 $@:腳本后面所有參數(shù),參數(shù)是獨立的,也是全部輸出 $0:當前執(zhí)行的進程/程序名 echo $0 $1~$9位置參數(shù)變量 ${10}~${n}擴展位置參數(shù)變量第10個位置變量必須用{}大括號括起來 ./1.shabc [root@MissHoushell01]#cat2.sh #!/bin/bash #xxxx echo"$0=$0" echo"$#=$#" echo"$*=$*" echo"$@=$@" echo"$1=$1" echo"$2=$2" echo"$3=$3" echo"$11=${11}" echo"$12=${12}" 了解$*和$@的區(qū)別: $*:表示將變量看成一個整體 $@:表示變量是獨立的 #!/bin/bash foriin"$@" do echo$i done echo"======我是分割線=======" foriin"$*" do echo$i done [root@MissHoushell01]#bash3.shabc a b c ======我是分割線======= abc
2. 什么時候需要定義變量?
如果某個內(nèi)容需要多次使用,并且在代碼中重復出現(xiàn),那么可以用變量代表該內(nèi)容。這樣在修改內(nèi)容的時候,僅僅需要修改變量的值。
在代碼運作的過程中,可能會把某些命令的執(zhí)行結(jié)果保存起來,后續(xù)代碼需要使用這些結(jié)果,就可以直接使用這個變量。
3. 變量的定義規(guī)則
1. 默認情況下,shell里定義的變量是不分類型的,可以給變量賦與任何類型的值;等號兩邊不能有空格,對于有空格的字符串做為賦值時,要用引號引起來 變量名=變量值 2. 變量的獲取方式:$變量名${變量名} [root@MissHoushell01]#a=12345678 [root@MissHoushell01]#echo$a 12345678 [root@MissHoushell01]#echo${a} 12345678 [root@MissHou shell01]# echo ${a3} a表示變量名;2表示從第3個字符開始;3表示后面3個字符 345 如果獲取變量的全部兩個都可以;如果獲取變量的某一部分,用${} 3.取消變量:unset變量名 4.變量名區(qū)分大小寫,同名稱但大小寫不同的變量名是不同的變量 5.變量名可以是字母或數(shù)字或下劃線,但是不能以數(shù)字開頭或者特殊字符 [root@MissHoushell01]#1a=hello -bash:1a=hello:commandnotfound [root@MissHoushell01]#?a=hello -bash:?a=hello:commandnotfound [root@MissHoushell01]#_a=hello [root@MissHoushell01]#echo$_a hello 6.命令的執(zhí)行結(jié)果可以保存到變量 [root@servershell01]#kernel=`uname-r` [root@servershell01]#echo$kernel 2.6.32-431.el6.x86_64 [root@servershell01]#name=$(uname-n) [root@servershell01]#echo$name server.itcast.cc 7.有類型變量declare -i將變量看成整數(shù) -r使變量只讀readonly -x標記變量通過環(huán)境導出export -a 指定為索引數(shù)組(普通數(shù)組);查看普通數(shù)組 -A 指定為關(guān)聯(lián)數(shù)組;查看關(guān)聯(lián)數(shù)組 [root@servershell01]#a=10 [root@servershell01]#b=20 [root@servershell01]#echo$a+$b 10+20 [root@servershell01]#declare-ia=2 [root@servershell01]#declare-ib=4 [root@servershell01]#declare-ic=$a+$b [root@servershell01]#echo$c 6 [root@servershell01]#AAAA=hello [root@servershell01]#exportAAAA [root@servershell01]#env|grepAAAA AAAA=hello [root@servershell01]#declare-xBBBB=hello [root@servershell01]#env|grepBBBB BBBB=hello 8.數(shù)組 普通數(shù)組:只能使用整數(shù)作為數(shù)組索引(元素的下標) 關(guān)聯(lián)數(shù)組:可以使用字符串作為數(shù)組索引(元素的下標) 普通數(shù)組定義:用括號來表示數(shù)組,數(shù)組元素(變量)用“空格”符號分割開。定義數(shù)組的一般形式為: 一次賦一個值: 變量名=變量值 array[0]=v1 array[1]=v2 array[3]=v3 一次賦多個值: array=(var1var2var3var4) array1=(`cat/etc/passwd`)//將文件中每一行賦值給array1數(shù)組 array2=(`ls/root`) array3=(harryamyjack"MissHou") array4=(1234"helloworld"[10]=linux) 讀取數(shù)組: ${array[i]}i表示元素的下標 使用@或*可以獲取數(shù)組中的所有元素: 獲取第一個元素 echo${array[0]} echo${array[*]}獲取數(shù)組里的所有元素 echo${#array[*]}獲取數(shù)組里所有元素個數(shù) echo${!array[@]}獲取數(shù)組元素的索引下標 echo ${array[@]2}訪問指定的元素;1代表從下標為1的元素開始獲取;2代表獲取后面幾個元素 [root@servershell01]#array[0]=var1 [root@servershell01]#array[1]=var2 [root@servershell01]#array[2]=var3 [root@servershell01]#array1=(uu1uu2uu3uu4) [root@servershell01]#ls 1.sh2.sh3.sh4.shpasswd [root@servershell01]#array2=(`ls./`) [root@servershell01]#array3=(jackharry"MissHou"[5]=tom) 查看普通數(shù)組信息: [root@servershell01]#declare-a declare-aarray='([0]="var1"[1]="var2"[2]="var3")' declare-aarray1='([0]="uu1"[1]="uu2"[2]="uu3"[3]="uu4")' declare-aarray2='([0]="1.sh"[1]="2.sh"[2]="3.sh"[3]="4.sh"[4]="passwd")' declare-aarray3='([0]="jack"[1]="harry"[2]="MissHou"[5]="tom")' [root@servershell01]# [root@servershell01]# [root@servershell01]#echo${array[*]} var1var2var3 [root@servershell01]#echo${array[@]} var1var2var3 [root@servershell01]#echo${array[2]} var3 [root@servershell01]#echo${array2[@]} 1.sh2.sh3.sh4.shpasswd [root@servershell01]#echo${array2[3]} 4.sh [root@servershell01]# [root@servershell01]#echo${array2[*]2} 3.sh4.sh [root@servershell01]#echo${#array2[*]} 5 [root@servershell01]#echo${!array2[*]} 01234 [root@servershell01]#echo${!array3[*]} 0125 關(guān)聯(lián)數(shù)組定義: 首先聲明關(guān)聯(lián)數(shù)組 declare-Aasso_array1 declare-Aasso_array2 declare-Aasso_array3 數(shù)組賦值: 一次賦一個值: 數(shù)組名[索引|下標]=變量值 [root@server~]#asso_array1[linux]=one [root@server~]#asso_array1[java]=two [root@server~]#asso_array1[php]=three 一次賦多個值: [root@server~]#asso_array2=([name1]=harry[name2]=jack[name3]=amy[name4]="MissHou") 查看關(guān)聯(lián)數(shù)組: [root@server~]#declare-A declare-Aasso_array1='([php]="three"[java]="two"[linux]="one")' declare-Aasso_array2='([name3]="amy"[name2]="jack"[name1]="harry"[name4]="MissHou")' [root@server~]#echo${asso_array1[linux]} one [root@server~]#echo${asso_array1[php]} three [root@server~]#echo${asso_array1[*]} threetwoone [root@server~]#echo${!asso_array1[*]} phpjavalinux [root@server~]#echo${#asso_array1[*]} 3 [root@server~]#echo${#asso_array2[*]} 4 [root@server~]#echo${!asso_array2[*]} name3name2name1name4 9.交互式定義變量的值read主要用于讓用戶去定義變量值 -p提示信息 -n字符數(shù)(限制變量值的字符數(shù)) -s不顯示 -t超時(默認單位秒)(限制用戶輸入變量值的超時時間) [root@MissHoushell01]#cat1.txt 10.1.1.1255.255.255.0 [root@MissHoushell01]#read-p"InputyourIPandNetmask:"ipmask1.txt? [root@MissHou?shell01]#?echo?$ip 10.1.1.1 [root@MissHou?shell01]#?echo?$mask 255.255.255.0 10.?其他變量(擴展) 1)取出一個目錄下的目錄和文件:dirname和 basename 2)變量"內(nèi)容"的刪除和替換 一個“%”代表從右往左去掉一個/key/ 兩個“%%”代表從右往左最大去掉/key/ 一個“#”代表從左往右去掉一個/key/ 兩個“##”代表從左往右最大去掉/key/ #?A=/root/Desktop/shell/mem.txt? #?echo?$A /root/Desktop/shell/mem.txt #?dirname?$A???取出目錄 /root/Desktop/shell #?basename?$A??取出文件 mem.txt #?url=www.taobao.com #?echo?${#url}?????????????獲取變量的長度 #?echo?${url#*.} #?echo?${url##*.} #?echo?${url%.*} #?echo?${url%%.*} ++++++++++++++++++++++++++++++++++++++++++++++++++ 以下內(nèi)容自己完成: 替換:/?和?// ?1015??echo?${url/ao/AO} ?1017??echo?${url//ao/AO}???貪婪替換 替代:?-?和?:-??+和:+ ?1019??echo?${abc-123} ?1020??abc=hello ?1021??echo?${abc-444} ?1022??echo?$abc ?1024??abc= ?1025??echo?${abc-222} ${變量名-新的變量值}?或者?${變量名=新的變量值} 變量沒有被賦值:會使用“新的變量值“?替代 變量有被賦值(包括空值):?不會被替代 ?1062??echo?${ABC:-123} ?1063??ABC=HELLO ?1064??echo?${ABC:-123} ?1065??ABC= ?1066??echo?${ABC:-123} ${變量名:-新的變量值}?或者?${變量名:=新的變量值} 變量沒有被賦值或者賦空值:會使用“新的變量值“?替代 變量有被賦值:?不會被替代 ?1116??echo?${abc=123} ?1118??echo?${abc:=123} [root@server?~]#?unset?abc [root@server?~]#?echo?${abc:+123} [root@server?~]#?abc=hello [root@server?~]#?echo?${abc:+123} 123 [root@server?~]#?abc= [root@server?~]#?echo?${abc:+123} ${變量名+新的變量值} 變量沒有被賦值或者賦空值:不會使用“新的變量值“?替代 變量有被賦值:?會被替代 [root@server?~]#?unset?abc [root@server?~]#?echo?${abc+123} [root@server?~]#?abc=hello [root@server?~]#?echo?${abc+123} 123 [root@server?~]#?abc= [root@server?~]#?echo?${abc+123} 123 ${變量名:+新的變量值} 變量沒有被賦值:不會使用“新的變量值“?替代 變量有被賦值(包括空值):?會被替代 [root@server?~]#?unset?abc [root@server?~]#?echo?${abc?123} -bash:?abc:?123 [root@server?~]#?abc=hello [root@server?~]#?echo?${abc?123} hello [root@server?~]#?abc= [root@server?~]#?echo?${abc?123} ${變量名?新的變量值} 變量沒有被賦值:提示錯誤信息 變量被賦值(包括空值):不會使用“新的變量值“?替代 [root@server?~]#?unset?abc [root@server?~]#?echo?${abc:?123} -bash:?abc:?123 [root@server?~]#?abc=hello [root@server?~]#?echo?${abc:?123} hello [root@server?~]#?abc= [root@server?~]#?echo?${abc:?123} -bash:?abc:?123 ${變量名:?新的變量值} 變量沒有被賦值或者賦空值時:提示錯誤信息 變量被賦值:不會使用“新的變量值“?替代 說明:?主要是當變量沒有賦值提示錯誤信息的,沒有賦值功能
簡單的四則運算
算術(shù)運算:默認情況下,shell就只能支持簡單的==整數(shù)==運算
+-*/%(取模,求余數(shù))
Bashshell的算術(shù)運算有四種方式: 1.使用$(()) 2.使用$[] 3.使用expr外部程式 4.使用let命令 注意: n=1 letn+=1等價于letn=n+1 思考:能不能用shell做小數(shù)運算? [root@servershell01]#echo1+1.5|bc 2.5 i++和++i(了解) 對變量的值的影響: [root@node1~]#i=1 [root@node1~]#leti++ [root@node1~]#echo$i 2 [root@node1~]#j=1 [root@node1~]#let++j [root@node1~]#echo$j 2 對表達式的值的影響: [root@node1~]#unsetij [root@node1~]#i=1;j=1 [root@node1~]#letx=i++先賦值,再運算 [root@node1~]#lety=++j先運算,再賦值 [root@node1~]#echo$i 2 [root@node1~]#echo$j 2 [root@node1~]#echo$x 1 [root@node1~]#echo$y 2
總結(jié):
$(())$[] expr注意空格,*要進行轉(zhuǎn)義 letn+=1等價letn=n+1 letn=n**5n有初值,然后求次冪 i++++i 對變量本身沒有影響(自己+1); 表達式中有影響;i++先賦值再運算++i先運算再賦值 letx=i++letx=++i
條件判斷
1. 語法格式
格式1:==test== 條件表達式
格式2:[條件表達式 ]
格式3:[[條件表達式 ]] 支持正則 =~
說明:
man test去查看,很多的參數(shù)都用來進行條件判斷
2. 條件判斷相關(guān)參數(shù)
與文件存在與否的判斷
-e是否存在不管是文件還是目錄,只要存在,條件就成立 -f是否為普通文件 -d是否為目錄 -Ssocket -ppipe -ccharacter -bblock -L軟link 三種語法格式: test-efile只要文件存在條件為真 [-d/shell01/dir1]判斷目錄是否存在,存在條件為真 [!-d/shell01/dir1]判斷目錄是否存在,不存在條件為真 [[-f/shell01/1.sh]]判斷文件是否存在,并且是一個普通的文件 -s判斷文件是否有內(nèi)容(大?。强瘴募l件滿足 說明:-s表示非空,!-s 表示空文件 說明:1.sh文件里有內(nèi)容的。 [root@servershell01]#test-s1.sh [root@servershell01]#echo$? 0 [root@servershell01]#touchaaa [root@servershell01]#cataaa [root@servershell01]#test-saaa [root@servershell01]#echo$? 1 [root@servershell01]#test!-saaa [root@servershell01]#echo$? 0 [root@servershell01]#test!-s1.sh [root@servershell01]#echo$? 1
文件權(quán)限相關(guān)的判斷
-r當前用戶對其是否可讀 -w當前用戶對其是否可寫 -x當前用戶對其是否可執(zhí)行 -u是否有suid -g是否sgid -k是否有t位
兩個文件的比較判斷
file1-ntfile2比較file1是否比file2新 file1-otfile2比較file1是否比file2舊 file1-effile2比較是否為同一個文件,或者用于判斷硬連接,是否指向同一個inode testfile1-ntfile2 [file1-otfile2]
整數(shù)之間的判斷
-eq相等 -ne不等 -gt大于 -lt小于 -ge大于等于 -le小于等于
字符串之間的判斷
-z是否為空字符串字符串長度為0,就成立 -n是否為非空字符串只要字符串非空,就是成立 string1=string2是否相等 string1!=string2不等 [root@servershell01]#AAA=hello [root@servershell01]#BBB=world [root@servershell01]#test-z$AAA [root@servershell01]#echo$? 1 [root@servershell01]#test-n$AAA [root@servershell01]#echo$? 0 [root@servershell01]#[$AAA=$BBB] [root@servershell01]#echo$? 1 [root@servershell01]#[$AAA!=$BBB] [root@servershell01]#echo$? 0
多重條件判斷
邏輯判斷符號: -a和&&(and邏輯與)兩個條件同時滿足,整個大條件為真 -o和||(or邏輯或)兩個條件滿足任意一個,整個大條件為真 [1-eq1-a1-ne0]整個表達式為真 [1-eq1]&&[1-ne0] [1-eq1-o1-ne1]整個表達式為真 [1-eq1]||[1-ne1] [root@servershell01]#[1-eq0]&&echotrue||echofalse false [root@servershell01]#[1-eq1]&&echotrue||echofalse true &&:前面的表達式為真 ||:前面的表達式為假 總結(jié): 1、;&&||都可以用來分割命令或者表達式 2、;完全不考慮前面的語句是否正確執(zhí)行,都會執(zhí)行;號后面的內(nèi)容 3、&&需要考慮&&前面的語句的正確性,前面語句正確執(zhí)行才會執(zhí)行&&后的內(nèi)容;反之亦然 make&&makeinstall 4、||需要考慮||前面的語句的非正確性,前面語句執(zhí)行錯誤才會執(zhí)行||后的內(nèi)容;反之亦然 5、如果&&和||一起出現(xiàn),從左往右依次看,按照以上原則
3. 示例
示例: 數(shù)值比較: [root@server~]#[$(id-u)-eq0]&&echo"theuserisadmin" [root@server~]$[$(id-u)-ne0]&&echo"theuserisnotadmin" [root@server~]$[$(id-u)-eq0]&&echo"theuserisadmin"||echo"theuserisnotadmin" [root@server~]#uid=`id-u` [root@server~]#test$uid-eq0&&echothisisadmin thisisadmin [root@server~]#[$(id-u)-ne0]||echothisisadmin thisisadmin [root@server~]#[$(id-u)-eq0]&&echothisisadmin||echothisisnotadmin thisisadmin [root@server~]#su-stu1 [stu1@server~]$[$(id-u)-eq0]&&echothisisadmin||echothisisnotadmin thisisnotadmin [stu1@server~]$ 類C風格的數(shù)值比較: 注意:在(())中,=表示賦值;==表示判斷 1159((1==2));echo$? 1160((1<2));echo?$? ?1161??((2>=1));echo$? 1162((2!=1));echo$? 1163((`id-u`==0));echo$? 1209((a=123));echo$a 1210unseta 1211((a==123));echo$? 字符串比較: 注意:雙引號引起來,看作一個整體;=和==在[字符串]比較中都表示判斷 1196a='helloworld';b=world 1197[$a=$b];echo$? 1198["$a"="$b"];echo$? 1199["$a"!="$b"];echo$? 1200["$a"!=="$b"];echo$?錯誤 1201["$a"=="$b"];echo$? 1202test"$a"!="$b";echo$? 思考:[]和[[]]有什么區(qū)別? 1213a= 1214test-z$a;echo$? 1215a=hello 1216test-z$a;echo$? 1217test-n$a;echo$? 1217test-n"$a";echo$? #[''=$a];echo$? -bash:[::unaryoperatorexpected 2 #[[''=$a]];echo$? 0 1278[1-eq0-a1-ne0];echo$? 1279[1-eq0&&1-ne0];echo$? 1280[[1-eq0&&1-ne0]];echo$?
-
Linux
+關(guān)注
關(guān)注
87文章
11207瀏覽量
208717 -
編寫
+關(guān)注
關(guān)注
0文章
29瀏覽量
8425 -
python
+關(guān)注
關(guān)注
55文章
4767瀏覽量
84375 -
Shell
+關(guān)注
關(guān)注
1文章
363瀏覽量
23257 -
腳本
+關(guān)注
關(guān)注
1文章
387瀏覽量
14811
原文標題:【建議收藏】一文吃透shell編寫工具及基本法則!
文章出處:【微信號:浩道linux,微信公眾號:浩道linux】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。
發(fā)布評論請先 登錄
相關(guān)推薦
評論