一: 什么是 Shell
Shell是一塊包裹著系統(tǒng)核心的殼,處于操作系統(tǒng)的最外層,與用戶直接對話,把用戶的輸入, 解釋給操作系統(tǒng),然后處理操作系統(tǒng)的輸出結(jié)果,輸出到屏幕給與用戶看到結(jié)果。
Shell是用戶與系統(tǒng)交互的主要方式之一。

在這里插入圖片描述
Shell的作用是
? 解釋執(zhí)行用戶輸入的命令或程序等
? 用戶輸入一條命令,Shell就解釋一條鍵盤輸入命令,Linux 給與響應(yīng)的方式,稱之為交互式

在這里插入圖片描述
我們想要獲取計算機的數(shù)據(jù),不可能每次都編寫程序,編譯后,再運行,再得到我們想要的,例如你想找到一個文件,可以先寫一段 C語言的代碼,然后調(diào)用系統(tǒng)函數(shù),通過 gcc 編譯后,運行程序才能找到文件。
因此有大牛開發(fā)出了Shell解釋器,能夠讓我們方便的使用 Linux,例如只要敲下 ls - lh 這樣的字符串,Shell解釋器就會針對這句話翻譯,解釋成 ls-l -h 然后執(zhí)行,通過終端輸出結(jié)果,無論是圖形化或是命令行界面。
即使我們用的圖形化,點點點的動作,區(qū)別也只是
? 命令行操作,Shell解釋執(zhí)行后,輸出結(jié)果到黑屏命令行界面
? 圖形化操作,Shell接受點擊動作,輸出圖案數(shù)據(jù)
常見的 Shell 類型
?Bash (Bourne Again Shell):
最廣泛使用的 Shell,是 GNU 項目的一部分,提供了豐富的功能和強大的腳本支持。
默認(rèn)的 Shell 為大多數(shù) Linux 發(fā)行版和 macOS(直到 macOS Mojave)。
?Sh (Bourne Shell):
最早的 Unix Shell,是 Bash 的前身,功能相對簡單。
?Tcsh (C Shell):
提供了類似于 C 語言的語法,適合熟悉 C 語言的用戶。
?Zsh (Z Shell):
提供了許多高級功能,如自動補全、主題支持等,是 macOS Catalina 及以后版本的默認(rèn) Shell。
?Fish (Friendly Interactive Shell):
一個現(xiàn)代的 Shell,強調(diào)用戶友好性和交互性,提供了智能的自動補全和語法高亮等功能。
二: 什么是 Shell 腳本
當(dāng)命令或者程序語句寫在文件中,我們執(zhí)行文件,讀取其中的代碼,這個程序文件就稱之為Shell腳本
在Shell腳本里定義多條 Linux 命令以及循環(huán)控制語句,然后將這些 Linux 命令一次性執(zhí)行完畢,執(zhí)行腳本文件的方式稱之為,非交互式方式,
? windows 中存在*.bat 批處理腳本
? Linux 中常用*.sh 腳本文件
Shell==腳本語言屬于一種弱類型語言==,無需聲明變量類型,直接定義使用強類型語言,必須先定義變量類型,確定是數(shù)字、字符串等,之后再賦予同類型的值 centos7 系統(tǒng)中支持的Shell情況,有如下種類
# cat /etc/shells # /etc/shells: valid login shells /bin/sh /bin/bash /usr/bin/bash /bin/rbash /usr/bin/rbash /bin/dash /usr/bin/dash /usr/bin/tmux /usr/bin/screen
Linux 默認(rèn)Shell
# echo $SHELL /bin/bash
Shell 腳本規(guī)則
在 Linux 系統(tǒng)中,Shell腳本或者稱之為 (bash shell程序) 通常都是 vim 編輯,由 Linux 命令、bash shell 指令、邏輯控制語句和注釋信息組成。
第一個 Shell 腳本
# vim test1.sh # cat test1.sh # 第一個 shell 腳本 這是注釋 #!/bin/bash echo"hello world!"
運行Shell腳本
# bash test1.sh hello world!
Shebang
計算機程序中Shebang指的是出現(xiàn)在文本文件的第一行前兩個字符#!
? 就是指明這個代碼文件用哪個解釋器去讀
在 Unix 系統(tǒng)中,程序會分析Shebang后面的內(nèi)容,作為解釋器的指令,例如
? 以#!/bin/bash開頭的文件,程序在執(zhí)行的時候會調(diào)用/bin/bash,也就是 bash 解釋器
? 以 #!/usr/bin/python 開頭的文件,代表指定python解釋器去執(zhí)行
? 以 #!/usr/bin/env 解釋器名稱 ,是一種在不同平臺上都能正確找到解釋器的辦法
注意事項:
? 如果腳本未指定Shebang,腳本執(zhí)行的時候,默認(rèn)用當(dāng)前 shell 去解釋腳本,即 $SHELL。
? 如果Shebang指定了可執(zhí)行的解釋器,如 /bin/bash /usr/bin/python ,腳本在執(zhí)行時,文件名會作為參數(shù)傳遞給解釋器
? 如果 #! 指定的解釋程序沒有可執(zhí)行權(quán)限,則會報錯“bad interpreter: Permission denied”。
? 如果 #! 指定的解釋程序不是一個可執(zhí)行文件,那么指定的解釋程序會被忽略,轉(zhuǎn)而交給當(dāng)前的 SHELL 去執(zhí)行這個腳本。
? 如果 #! 指定的解釋程序不存在,那么會報錯 “bad interpreter: No such file or directory”。
? #! 之后的解釋程序,需要寫其絕對路徑 (如:#!/bin/bash),它是不會自動到 $PATH 中尋找解釋器的。。
? 如果你使用 “bash test.sh” 這樣的命令來執(zhí)行腳本,那么 #! 這一行將會被忽略掉,解釋器當(dāng)然是用命令行中顯式指定的 bash。
腳本的常用執(zhí)行方式
第一種:采用bash或sh + 腳本的相對路徑或絕對路徑(不用賦予腳本 +x 權(quán)限)
sh + 腳本的相對路徑
$ sh helloworld.sh Helloworld
sh + 腳本的絕對路徑
$ sh /home/zfox/datas/helloworld.sh helloworld
bash+腳本的相對路徑
$ bash helloworld.sh Helloworld
bash + 腳本的絕對路徑
$ bash /home/zfox/datas/helloworld.sh Helloworld
第二種:采用輸入腳本的絕對路徑或相對路徑執(zhí)行腳本(必須具有可執(zhí)行權(quán)限 + x)
(a)首先要賦予 helloworld.sh 腳本的 + x權(quán)限
$ chmod777helloworld.sh
(b)執(zhí)行腳本
相對路徑(推薦使用)
$ ./helloworld.sh Helloworld
絕對路徑
$ /home/zfox/datas/helloworld.sh Helloworld
注意:第一種執(zhí)行方法,本質(zhì)是 bash解析器 幫你執(zhí)行腳本,所以腳本本身不需要執(zhí)行權(quán)限。第二種執(zhí)行方法,本質(zhì)是腳本需要自己執(zhí)行,所以需要執(zhí)行權(quán)限
第二個 Shell 腳本:多命令處理
(1)需求: 在/home/zfox/目錄下創(chuàng)建一個ljw.txt, 在ljw.txt文件中增加I love ljw
(2)案例實操:
$ touch batch.sh $ vim batch.sh
在 batch.sh 中輸入如下內(nèi)容
#!/bin/bash cd /home/zfox touch ljw.txt echo"I love ljw" ljw.txt
Shell 的優(yōu)勢
雖然有諸多腳本編程語言,但是對于 Linux 操作系統(tǒng)內(nèi)部應(yīng)用而言,Shell是最好的工具,Linux 底層命令都支持Shell語句,以及結(jié)合三劍客 (grep、sed、awk) 進(jìn)行高級用法。
? 擅長系統(tǒng)管理腳本開發(fā),如軟件啟停腳本、監(jiān)控報警腳本、日志分析腳本
每個語言都有自己擅長的地方,揚長避短,達(dá)到高效運維的目的是最合適的
三: Shell 中的變量
? 變量定義與賦值,注意變量與值之間不得有空格
name="zfox" 變量名 變量類型,bash默認(rèn)把所有變量都認(rèn)為是字符串 bash變量是弱類型,無需事先聲明類型,是將聲明和賦值同時進(jìn)行
? 變量替換寫弓|用
# name="zfox帶你學(xué)bash"
# echo ${name}
zfox帶你學(xué)bash
# echo $name # 可以省略花括號
zfox帶你學(xué)bash
? 變量名規(guī)則
? 名稱定義要做到見名知意,切按照規(guī)則來,切不得引用保留關(guān)鍵字(help檢查保留字)
? 只能包含數(shù)字、字母、下劃線
? 不能以數(shù)字開頭
? 不能用標(biāo)點符號
? 變量名嚴(yán)格區(qū)分大小寫
? 變量的作用域
? 本地變量。只針對當(dāng)前的 shell 進(jìn)程
系統(tǒng)變量
1)常用系統(tǒng)變量
HOME、PWD、SHELL、USER等
2)案例實操
(1)查看系統(tǒng)變量的值
$ echo $HOME /home/zfox
(2)顯示當(dāng)前 Shell 中所有變量:set
$set BASH=/bin/bash BASH_ALIASES=() BASH_ARGC=() BASH_ARGV=()
自定義變量
1.基本語法
(1)定義變量:變量=值
(2)撤銷變量:unset 變量
(3)聲明靜態(tài)變量:readonly 變量,注意:不能unset
單引號 雙引號區(qū)別
單引號變量,不識別特殊語法
雙引號變量,能識別特殊符號
反引號,引用命令執(zhí)行結(jié)果,等于 $() 用法
舉例子:
# name="奧里給"
# echo ${name}
奧里給
# 單引號
# name2='${name}'
# echo $name2
${name}
# 雙引號
# name2="${name}"
# echo $name2
奧里給
特殊變量
? $?
? 0 成功
? 1-255 錯誤碼
Shell 的特殊變量,用在如腳本,函數(shù)傳遞參數(shù)使用,有如下特殊的,位置參數(shù)變量
$0 獲取shel1腳本文件名,以及腳本路徑
$n 獲取shel1腳本的第n個參數(shù),n在1~9之間,如$1,$2,$9,大于9則需要寫,${10},參數(shù)空格隔開
$# 獲取執(zhí)行的she11腳本后面的參數(shù)總個數(shù)
$* 獲取she11腳本所有參數(shù),不加引號等同于 $@ 作用,加上引號"$*"作用是 接收所有參數(shù)為單個字符串,"$1 $2.
$@ 不加引號,效果同上,加引號,是接收所有參數(shù)為獨立字符串,如"$1" "$2" "$3”...,空格保留
特殊變量實踐
#! bin/bash # 注意單引號和雙引號的區(qū)別 echo'特殊變量 $0 $1 $2 ... 的實踐' echo'結(jié)果: '$0$1$2 echo'############################' echo'特殊變量$# 獲取參數(shù)個數(shù)的總數(shù)' echo'結(jié)果: '$# echo'############################' echo'特殊變量$* 實踐' echo'結(jié)果: '$* echo'############################' echo'特殊變量 $@ 實踐' echo'結(jié)果: '$@
#! /bin/bash # $* 和 $@ 的區(qū)別 echo'print each param from $*' forvarin"$*" do echo"$var" done echo'print each param from $@' forvarin"$@" do echo"$var" done
$*和$@的區(qū)別你了解嗎? $*和 $@ 都表示傳遞給函數(shù)或腳本的所有參數(shù) 當(dāng) $*和 $@ 不被雙引號""包圍時,它們之間沒有任何區(qū)別,都是將接收到的每個參數(shù)看做一份數(shù)據(jù),彼此之間以空格來分隔。 但是當(dāng)它們被雙引號""包含時,就會有區(qū)別了: "$*"會將所有的參數(shù)從整體上看做一份數(shù)據(jù),而不是把每個參數(shù)都看做一份數(shù)據(jù)。'yu chao 180 180 180 180" "$@"仍然將每個參數(shù)都看作一份數(shù)據(jù),彼此之間是獨立的。 "chao' "180" "180" "180" 比如傳遞了5個參數(shù),那么對于"$*"來說,這5個參數(shù)會合并到一起形成一份數(shù)據(jù),它們之間是無法分割的;而對于"$@"來說,這5個參數(shù)是相互獨立的,它們是5份數(shù)據(jù)。 如果使用 echo 直接輸出"$*"和"$@"做對比,是看不出區(qū)別的;但如果使用for循環(huán)來逐個輸出數(shù)據(jù),立即就能看出區(qū)別來。
Shell 變量面試題
問,如下輸入什么內(nèi)容
# cat test.sh user1=`whoami` # sh test.sh # echo $user1 A.當(dāng)前用戶 B.zfox c.空 答案選c
`linux命令`
在 linux 中反引號,中的命令執(zhí)行結(jié)果會被保留下來
# name=`ls` # echo $name test1.sh test2.sh test3.sh
解答:
1. 每次調(diào)用 bash/sh 解釋器執(zhí)行腳本,都會開啟一個子 shell,因此不保留當(dāng)前的 shell 變量,通過 pstree 命令檢查進(jìn)程樹
2. 調(diào)用 source 或者 點符號,在當(dāng)前 shell 環(huán)境加載腳本,因此保留變量
環(huán)境變量設(shè)置
環(huán)境變量一般指的是用 export 內(nèi)置命令導(dǎo)出的變量,用于定義 shell 的運行環(huán)境、保證 shell 命令的正確執(zhí)行。
shell 通過環(huán)境變量確定登錄的用戶名、PATH路徑、文件系統(tǒng)等各種應(yīng)用。
環(huán)境變量可以在命令行中臨時創(chuàng)建,但是用戶退出shell終端,變量即丟失,如要永久生效,需要修改環(huán)境變量配置文件
? 用戶個人配置文件 ~/.bash profile、 ~/.bashrc 遠(yuǎn)程登錄用戶特有文件
? 全局配置文件 /etc/profile/etc/bashrc,且系統(tǒng)建議最好創(chuàng)建在 /etc/profile.d/,而非直接修改主文件,修改全局配置文件,影響所有登錄系統(tǒng)的用戶
檢查系統(tǒng)環(huán)境變量的命令
? set,輸出所有變量,包括全局變量、局部變量
? env,當(dāng)前用戶的所有環(huán)境變量,包括全局環(huán)境變量和局部環(huán)境變量
? declare,輸出所有的變量,如同 set
? export,顯示和設(shè)置環(huán)境變量值
撤銷環(huán)境變量
? unset 變量名,刪除變量或函數(shù)
設(shè)置只讀變量
? readonly,只有shell結(jié)束,只讀變量失效
直接readonly顯示當(dāng)前系統(tǒng)只讀變量 # readonly name="超哥" # name="chaochao" -bash只讀變量
環(huán)境變量初始化與加載順序

在這里插入圖片描述
四: Shell 子串
bsah 一些基礎(chǔ)的內(nèi)置命令
echo eval exec export read shift
echo 命令
-n 不換行輸出 -e 解析字符串中的特殊符號 換行 回車 制表符 四個空格 退格 # echo 你真胖;echo 你還挺可愛你真胖 你還挺可愛 # 不換行打印 # echo -n 你真胖;echo 你還挺可愛 你真胖你還挺可愛 # echo -n 你真胖;echo -n 你還挺可愛你真胖你還挺可愛 # # echo -e "我看你挺 好的" 我看你挺 好的 # printf printf"你好 我是 吳彥祖" 你好 我是 吳彥祖
eval
執(zhí)行多個命令
#evalls;cd/tmp del_data.sh hello.py special_var.sh t1.sh different.sh hello.sh nohup.out str1 test.txt
exec
不創(chuàng)建子進(jìn)程,執(zhí)行后續(xù)命令, 且執(zhí)行完畢后,自動 exit
# exec date Fri25Apr202508:56:41AM CST Connection closed. Disconnectedfromremotehost(Ubuntu-tencnt) at 0841.
Shell 子串的花式用法
${變量} 返回變量值
${#變量} 返回變量長度,字符長度
${變量:start} 返回變量 offset 數(shù)值之后的字符
${變量length} 提取 offset 之后的 length 限制的字符
${變量#word} 從變量開頭刪除最短匹配的 word 子串
${變量##word} 從變量開頭,刪除最長匹配的 word
${變量%word} 從變量結(jié)尾刪除最短的 word
${變量%%word} 從變量結(jié)尾開始刪除最長匹配的 word
${變量/pattern/string} 用string代替第一個匹配的 pattern
${變量//pattern/string) 用 string 代替所有的 pattern
# name="yuchao180'
# echo $name
yuchao180
# echo ${name}
yuchao188
# echo ${#name}
9
# 截取子串的用法
# echo ${name:3}
hao180
# echo ${name:5}
o180
#設(shè)置起點,以及元素長度
# echo ${name4}
chao
? 多種統(tǒng)計長度的命令
# echo $name yuchao180 # echo $name | wc -l 1 # echo $name |wc -L 9 # 解釋wc命令參數(shù)用法 -l 行數(shù) -L 最長一行的長度 # cat test1.txt | wc -l 3 # cat test1.txt | wc -L 8
? 統(tǒng)計命令執(zhí)行速度
字符串長度統(tǒng)計方式這么多,誰最快?
time命令,統(tǒng)計命令執(zhí)行時長
for 循環(huán)的 shell 編程知識語法
fornumberin{1..100}
do
echo $number
done
寫在一行的方法
fornumin{1..100};doecho $num; done
# 1.方法
# for n in {1..3}; do str1=`seg -s ":" 10`; echo $str1; done
1:2:3:4:5:6:7:8:9:10
1:2:3:4:5:6:7:8:9:10
1:2:3:4:5:6:7:8:9:10
# 結(jié)合 time 命令 ${#變量} 計算時間是13s
# time for n in {1..10000}; do char=`seq -s "chaoge" 100`; echo ${#char} &/dev/null; done
real 0m13.956s 實際運行的時間
user 0m6.005s 用戶態(tài)執(zhí)行的時間
sys 0m5.868s 內(nèi)核態(tài)執(zhí)行的時間
# 使用 wc -L 命令計算時間
# time for n in {1..10000}; do char=`seq -s "chaoge" 100`; echo ${char} | wc-L &/dev/null; done
real 0m49.262s
user 0m18.843s
sys 0m24.905s
# expr命令的 length 函數(shù)統(tǒng)計
# time for n in {1..10000}; do char=`seq -s "chaoge" 100`; expr length "${char}" &/dev/null; done
real 0m28.511s
user 0m11.960s
sys 0m12.046s
Shell編程,盡量使用 linux 內(nèi)置的命令,內(nèi)置的操作,和內(nèi)置的函數(shù),C語言開發(fā),效率最高,盡可能的減少管道符的操作
字符串截取
刪除匹配到的子串
# name="I am chaoge"
# echo $name
I am chaoge
# echo ${name2}
am
# echo ${name5}
m cha
# name2="abcABC123ABcabc"
# #從開頭匹配字符刪除
# echo ${name2#a*c}
ABC123ABCabc
# echo ${name2##a*c}
# 利用%形式,從后向前匹配截取
# name2=abcABC123ABcabc
# echo ${name2%a*c}
abCABC123ABC
# echo ${name2%%a*c}
# echo ${name2%%a*C}
abcABC123ABCabc
# echo ${name2%a*C}
abcABC123ABCabc
替換字符串
# str1="Hello,man,i am your brother."
# echo $str1
Hello,man,i am your brother.
# echo ${str1/man/boy}
Hello,boy,i am your brother.
#多次匹配替換
# echo $str1
Hello,man,i am your brother.
# echo ${str1/o/0}
HellO,man,i am your brother.
# echo ${str1//o/O}
HellO,man,i am yOur brOther.
應(yīng)用:批量修改文件名
創(chuàng)建一批文件
# touch chaochao_{1..5}_finished.jpg
# touch chaochao_{1..5}_finished.png
去掉剩下的所有 jpg 文件的 _finished 字符
編寫 Shell 腳本如下:
#! /bin/bash
forfile_namein`ls *fin*jpg`;domv $file_name `echo ${file_name//_finished/}` ; done
特殊 Shell 擴展變量
如果parameter變量值為空,返回word字符串,賦值給result變量
result=${parameter:-word}
如果para變量為空,則word替代變量值,且返回其值
result=${parameter:=word}
如果para變量為空,word當(dāng)作stderr輸出,否則輸出變量值
用于設(shè)置變量為空導(dǎo)致錯誤時,返回的錯誤信息
result=$fparameter:?word?
如果para變量為空,什么都不做,否則word返回
result=${parameter:+word}
鏈接:https://blog.csdn.net/weixin_50776420/article/details/147463567?spm=1001.2014.3001.5501
-
操作系統(tǒng)
+關(guān)注
關(guān)注
37文章
7423瀏覽量
129533 -
Shell
+關(guān)注
關(guān)注
1文章
375瀏覽量
25456 -
腳本
+關(guān)注
關(guān)注
1文章
411瀏覽量
29258
原文標(biāo)題:Shell腳本黑科技:5分鐘學(xué)會自動化運維,效率翻倍
文章出處:【微信號:magedu-Linux,微信公眾號:馬哥Linux運維】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。
發(fā)布評論請先 登錄
[Shell腳本專家指南]人民郵電出版社.掃描版
linux shell 腳本入門
嵌入式和物聯(lián)網(wǎng)的shell腳本學(xué)習(xí)指南之shell腳本入門免費下載
109個實用shell腳本分享
shell腳本基礎(chǔ)知識
Linux Shell腳本經(jīng)典案例分享
Shell腳本入門指南
評論