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

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

在這里插入圖片描述
我們想要獲取計(jì)算機(jī)的數(shù)據(jù),不可能每次都編寫(xiě)程序,編譯后,再運(yùn)行,再得到我們想要的,例如你想找到一個(gè)文件,可以先寫(xiě)一段 C語(yǔ)言的代碼,然后調(diào)用系統(tǒng)函數(shù),通過(guò) gcc 編譯后,運(yùn)行程序才能找到文件。
因此有大牛開(kāi)發(fā)出了Shell解釋器,能夠讓我們方便的使用 Linux,例如只要敲下 ls - lh 這樣的字符串,Shell解釋器就會(huì)針對(duì)這句話翻譯,解釋成 ls-l -h 然后執(zhí)行,通過(guò)終端輸出結(jié)果,無(wú)論是圖形化或是命令行界面。
即使我們用的圖形化,點(diǎn)點(diǎn)點(diǎn)的動(dòng)作,區(qū)別也只是
? 命令行操作,Shell解釋執(zhí)行后,輸出結(jié)果到黑屏命令行界面
? 圖形化操作,Shell接受點(diǎn)擊動(dòng)作,輸出圖案數(shù)據(jù)
常見(jiàn)的 Shell 類型
?Bash (Bourne Again Shell):
最廣泛使用的 Shell,是 GNU 項(xiàng)目的一部分,提供了豐富的功能和強(qiáng)大的腳本支持。
默認(rèn)的 Shell 為大多數(shù) Linux 發(fā)行版和 macOS(直到 macOS Mojave)。
?Sh (Bourne Shell):
最早的 Unix Shell,是 Bash 的前身,功能相對(duì)簡(jiǎn)單。
?Tcsh (C Shell):
提供了類似于 C 語(yǔ)言的語(yǔ)法,適合熟悉 C 語(yǔ)言的用戶。
?Zsh (Z Shell):
提供了許多高級(jí)功能,如自動(dòng)補(bǔ)全、主題支持等,是 macOS Catalina 及以后版本的默認(rèn) Shell。
?Fish (Friendly Interactive Shell):
一個(gè)現(xiàn)代的 Shell,強(qiáng)調(diào)用戶友好性和交互性,提供了智能的自動(dòng)補(bǔ)全和語(yǔ)法高亮等功能。
二: 什么是 Shell 腳本
當(dāng)命令或者程序語(yǔ)句寫(xiě)在文件中,我們執(zhí)行文件,讀取其中的代碼,這個(gè)程序文件就稱之為Shell腳本
在Shell腳本里定義多條 Linux 命令以及循環(huán)控制語(yǔ)句,然后將這些 Linux 命令一次性執(zhí)行完畢,執(zhí)行腳本文件的方式稱之為,非交互式方式,
? windows 中存在*.bat 批處理腳本
? Linux 中常用*.sh 腳本文件
Shell==腳本語(yǔ)言屬于一種弱類型語(yǔ)言==,無(wú)需聲明變量類型,直接定義使用強(qiáng)類型語(yǔ)言,必須先定義變量類型,確定是數(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 指令、邏輯控制語(yǔ)句和注釋信息組成。
第一個(gè) Shell 腳本
# vim test1.sh # cat test1.sh # 第一個(gè) shell 腳本 這是注釋 #!/bin/bash echo"hello world!"
運(yùn)行Shell腳本
# bash test1.sh hello world!
Shebang
計(jì)算機(jī)程序中Shebang指的是出現(xiàn)在文本文件的第一行前兩個(gè)字符#!
? 就是指明這個(gè)代碼文件用哪個(gè)解釋器去讀
在 Unix 系統(tǒng)中,程序會(huì)分析Shebang后面的內(nèi)容,作為解釋器的指令,例如
? 以#!/bin/bash開(kāi)頭的文件,程序在執(zhí)行的時(shí)候會(huì)調(diào)用/bin/bash,也就是 bash 解釋器
? 以 #!/usr/bin/python 開(kāi)頭的文件,代表指定python解釋器去執(zhí)行
? 以 #!/usr/bin/env 解釋器名稱 ,是一種在不同平臺(tái)上都能正確找到解釋器的辦法
注意事項(xiàng):
? 如果腳本未指定Shebang,腳本執(zhí)行的時(shí)候,默認(rèn)用當(dāng)前 shell 去解釋腳本,即 $SHELL。
? 如果Shebang指定了可執(zhí)行的解釋器,如 /bin/bash /usr/bin/python ,腳本在執(zhí)行時(shí),文件名會(huì)作為參數(shù)傳遞給解釋器
? 如果 #! 指定的解釋程序沒(méi)有可執(zhí)行權(quán)限,則會(huì)報(bào)錯(cuò)“bad interpreter: Permission denied”。
? 如果 #! 指定的解釋程序不是一個(gè)可執(zhí)行文件,那么指定的解釋程序會(huì)被忽略,轉(zhuǎn)而交給當(dāng)前的 SHELL 去執(zhí)行這個(gè)腳本。
? 如果 #! 指定的解釋程序不存在,那么會(huì)報(bào)錯(cuò) “bad interpreter: No such file or directory”。
? #! 之后的解釋程序,需要寫(xiě)其絕對(duì)路徑 (如:#!/bin/bash),它是不會(huì)自動(dòng)到 $PATH 中尋找解釋器的。。
? 如果你使用 “bash test.sh” 這樣的命令來(lái)執(zhí)行腳本,那么 #! 這一行將會(huì)被忽略掉,解釋器當(dāng)然是用命令行中顯式指定的 bash。
腳本的常用執(zhí)行方式
第一種:采用bash或sh + 腳本的相對(duì)路徑或絕對(duì)路徑(不用賦予腳本 +x 權(quán)限)
sh + 腳本的相對(duì)路徑
$ sh helloworld.sh Helloworld
sh + 腳本的絕對(duì)路徑
$ sh /home/zfox/datas/helloworld.sh helloworld
bash+腳本的相對(duì)路徑
$ bash helloworld.sh Helloworld
bash + 腳本的絕對(duì)路徑
$ bash /home/zfox/datas/helloworld.sh Helloworld
第二種:采用輸入腳本的絕對(duì)路徑或相對(duì)路徑執(zhí)行腳本(必須具有可執(zhí)行權(quán)限 + x)
(a)首先要賦予 helloworld.sh 腳本的 + x權(quán)限
$ chmod777helloworld.sh
(b)執(zhí)行腳本
相對(duì)路徑(推薦使用)
$ ./helloworld.sh Helloworld
絕對(duì)路徑
$ /home/zfox/datas/helloworld.sh Helloworld
注意:第一種執(zhí)行方法,本質(zhì)是 bash解析器 幫你執(zhí)行腳本,所以腳本本身不需要執(zhí)行權(quán)限。第二種執(zhí)行方法,本質(zhì)是腳本需要自己執(zhí)行,所以需要執(zhí)行權(quán)限
第二個(gè) Shell 腳本:多命令處理
(1)需求: 在/home/zfox/目錄下創(chuàng)建一個(gè)ljw.txt, 在ljw.txt文件中增加I love ljw
(2)案例實(shí)操:
$ 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)勢(shì)
雖然有諸多腳本編程語(yǔ)言,但是對(duì)于 Linux 操作系統(tǒng)內(nèi)部應(yīng)用而言,Shell是最好的工具,Linux 底層命令都支持Shell語(yǔ)句,以及結(jié)合三劍客 (grep、sed、awk) 進(jìn)行高級(jí)用法。
? 擅長(zhǎng)系統(tǒng)管理腳本開(kāi)發(fā),如軟件啟停腳本、監(jiān)控報(bào)警腳本、日志分析腳本
每個(gè)語(yǔ)言都有自己擅長(zhǎng)的地方,揚(yáng)長(zhǎng)避短,達(dá)到高效運(yùn)維的目的是最合適的
三: Shell 中的變量
? 變量定義與賦值,注意變量與值之間不得有空格
name="zfox" 變量名 變量類型,bash默認(rèn)把所有變量都認(rèn)為是字符串 bash變量是弱類型,無(wú)需事先聲明類型,是將聲明和賦值同時(shí)進(jìn)行
? 變量替換寫(xiě)弓|用
# name="zfox帶你學(xué)bash"
# echo ${name}
zfox帶你學(xué)bash
# echo $name # 可以省略花括號(hào)
zfox帶你學(xué)bash
? 變量名規(guī)則
? 名稱定義要做到見(jiàn)名知意,切按照規(guī)則來(lái),切不得引用保留關(guān)鍵字(help檢查保留字)
? 只能包含數(shù)字、字母、下劃線
? 不能以數(shù)字開(kāi)頭
? 不能用標(biāo)點(diǎn)符號(hào)
? 變量名嚴(yán)格區(qū)分大小寫(xiě)
? 變量的作用域
? 本地變量。只針對(duì)當(dāng)前的 shell 進(jìn)程
系統(tǒng)變量
1)常用系統(tǒng)變量
HOME、PWD、SHELL、USER等
2)案例實(shí)操
(1)查看系統(tǒng)變量的值
$ echo $HOME /home/zfox
(2)顯示當(dāng)前 Shell 中所有變量:set
$set BASH=/bin/bash BASH_ALIASES=() BASH_ARGC=() BASH_ARGV=()
自定義變量
1.基本語(yǔ)法
(1)定義變量:變量=值
(2)撤銷變量:unset 變量
(3)聲明靜態(tài)變量:readonly 變量,注意:不能unset
單引號(hào) 雙引號(hào)區(qū)別
單引號(hào)變量,不識(shí)別特殊語(yǔ)法
雙引號(hào)變量,能識(shí)別特殊符號(hào)
反引號(hào),引用命令執(zhí)行結(jié)果,等于 $() 用法
舉例子:
# name="奧里給"
# echo ${name}
奧里給
# 單引號(hào)
# name2='${name}'
# echo $name2
${name}
# 雙引號(hào)
# name2="${name}"
# echo $name2
奧里給
特殊變量
? $?
? 0 成功
? 1-255 錯(cuò)誤碼
Shell 的特殊變量,用在如腳本,函數(shù)傳遞參數(shù)使用,有如下特殊的,位置參數(shù)變量
$0 獲取shel1腳本文件名,以及腳本路徑
$n 獲取shel1腳本的第n個(gè)參數(shù),n在1~9之間,如$1,$2,$9,大于9則需要寫(xiě),${10},參數(shù)空格隔開(kāi)
$# 獲取執(zhí)行的she11腳本后面的參數(shù)總個(gè)數(shù)
$* 獲取she11腳本所有參數(shù),不加引號(hào)等同于 $@ 作用,加上引號(hào)"$*"作用是 接收所有參數(shù)為單個(gè)字符串,"$1 $2.
$@ 不加引號(hào),效果同上,加引號(hào),是接收所有參數(shù)為獨(dú)立字符串,如"$1" "$2" "$3”...,空格保留
特殊變量實(shí)踐
#! bin/bash # 注意單引號(hào)和雙引號(hào)的區(qū)別 echo'特殊變量 $0 $1 $2 ... 的實(shí)踐' echo'結(jié)果: '$0$1$2 echo'############################' echo'特殊變量$# 獲取參數(shù)個(gè)數(shù)的總數(shù)' echo'結(jié)果: '$# echo'############################' echo'特殊變量$* 實(shí)踐' echo'結(jié)果: '$* echo'############################' echo'特殊變量 $@ 實(shí)踐' 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) $*和 $@ 不被雙引號(hào)""包圍時(shí),它們之間沒(méi)有任何區(qū)別,都是將接收到的每個(gè)參數(shù)看做一份數(shù)據(jù),彼此之間以空格來(lái)分隔。 但是當(dāng)它們被雙引號(hào)""包含時(shí),就會(huì)有區(qū)別了: "$*"會(huì)將所有的參數(shù)從整體上看做一份數(shù)據(jù),而不是把每個(gè)參數(shù)都看做一份數(shù)據(jù)。'yu chao 180 180 180 180" "$@"仍然將每個(gè)參數(shù)都看作一份數(shù)據(jù),彼此之間是獨(dú)立的。 "chao' "180" "180" "180" 比如傳遞了5個(gè)參數(shù),那么對(duì)于"$*"來(lái)說(shuō),這5個(gè)參數(shù)會(huì)合并到一起形成一份數(shù)據(jù),它們之間是無(wú)法分割的;而對(duì)于"$@"來(lái)說(shuō),這5個(gè)參數(shù)是相互獨(dú)立的,它們是5份數(shù)據(jù)。 如果使用 echo 直接輸出"$*"和"$@"做對(duì)比,是看不出區(qū)別的;但如果使用for循環(huán)來(lái)逐個(gè)輸出數(shù)據(jù),立即就能看出區(qū)別來(lái)。
Shell 變量面試題
問(wèn),如下輸入什么內(nèi)容
# cat test.sh user1=`whoami` # sh test.sh # echo $user1 A.當(dāng)前用戶 B.zfox c.空 答案選c
`linux命令`
在 linux 中反引號(hào),中的命令執(zhí)行結(jié)果會(huì)被保留下來(lái)
# name=`ls` # echo $name test1.sh test2.sh test3.sh
解答:
1. 每次調(diào)用 bash/sh 解釋器執(zhí)行腳本,都會(huì)開(kāi)啟一個(gè)子 shell,因此不保留當(dāng)前的 shell 變量,通過(guò) pstree 命令檢查進(jìn)程樹(shù)
2. 調(diào)用 source 或者 點(diǎn)符號(hào),在當(dāng)前 shell 環(huán)境加載腳本,因此保留變量
環(huán)境變量設(shè)置
環(huán)境變量一般指的是用 export 內(nèi)置命令導(dǎo)出的變量,用于定義 shell 的運(yùn)行環(huán)境、保證 shell 命令的正確執(zhí)行。
shell 通過(guò)環(huán)境變量確定登錄的用戶名、PATH路徑、文件系統(tǒng)等各種應(yīng)用。
環(huán)境變量可以在命令行中臨時(shí)創(chuàng)建,但是用戶退出shell終端,變量即丟失,如要永久生效,需要修改環(huán)境變量配置文件
? 用戶個(gè)人配置文件 ~/.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 解析字符串中的特殊符號(hào) 換行 回車 制表符 四個(gè)空格 退格 # echo 你真胖;echo 你還挺可愛(ài)你真胖 你還挺可愛(ài) # 不換行打印 # echo -n 你真胖;echo 你還挺可愛(ài) 你真胖你還挺可愛(ài) # echo -n 你真胖;echo -n 你還挺可愛(ài)你真胖你還挺可愛(ài) # # echo -e "我看你挺 好的" 我看你挺 好的 # printf printf"你好 我是 吳彥祖" 你好 我是 吳彥祖
eval
執(zhí)行多個(gè)命令
#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í)行完畢后,自動(dòng) exit
# exec date Fri25Apr202508:56:41AM CST Connection closed. Disconnectedfromremotehost(Ubuntu-tencnt) at 0841.
Shell 子串的花式用法
${變量} 返回變量值
${#變量} 返回變量長(zhǎng)度,字符長(zhǎng)度
${變量:start} 返回變量 offset 數(shù)值之后的字符
${變量length} 提取 offset 之后的 length 限制的字符
${變量#word} 從變量開(kāi)頭刪除最短匹配的 word 子串
${變量##word} 從變量開(kāi)頭,刪除最長(zhǎng)匹配的 word
${變量%word} 從變量結(jié)尾刪除最短的 word
${變量%%word} 從變量結(jié)尾開(kāi)始刪除最長(zhǎng)匹配的 word
${變量/pattern/string} 用string代替第一個(gè)匹配的 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è)置起點(diǎn),以及元素長(zhǎng)度
# echo ${name4}
chao
? 多種統(tǒng)計(jì)長(zhǎng)度的命令
# echo $name yuchao180 # echo $name | wc -l 1 # echo $name |wc -L 9 # 解釋wc命令參數(shù)用法 -l 行數(shù) -L 最長(zhǎng)一行的長(zhǎng)度 # cat test1.txt | wc -l 3 # cat test1.txt | wc -L 8
? 統(tǒng)計(jì)命令執(zhí)行速度
字符串長(zhǎng)度統(tǒng)計(jì)方式這么多,誰(shuí)最快?
time命令,統(tǒng)計(jì)命令執(zhí)行時(shí)長(zhǎng)
for 循環(huán)的 shell 編程知識(shí)語(yǔ)法
fornumberin{1..100}
do
echo $number
done
寫(xiě)在一行的方法
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 命令 ${#變量} 計(jì)算時(shí)間是13s
# time for n in {1..10000}; do char=`seq -s "chaoge" 100`; echo ${#char} &/dev/null; done
real 0m13.956s 實(shí)際運(yùn)行的時(shí)間
user 0m6.005s 用戶態(tài)執(zhí)行的時(shí)間
sys 0m5.868s 內(nèi)核態(tài)執(zhí)行的時(shí)間
# 使用 wc -L 命令計(jì)算時(shí)間
# 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)計(jì)
# 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語(yǔ)言開(kāi)發(fā),效率最高,盡可能的減少管道符的操作
字符串截取
刪除匹配到的子串
# name="I am chaoge"
# echo $name
I am chaoge
# echo ${name2}
am
# echo ${name5}
m cha
# name2="abcABC123ABcabc"
# #從開(kāi)頭匹配字符刪除
# 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 字符
編寫(xiě) Shell 腳本如下:
#! /bin/bash
forfile_namein`ls *fin*jpg`;domv $file_name `echo ${file_name//_finished/}` ; done
特殊 Shell 擴(kuò)展變量
如果parameter變量值為空,返回word字符串,賦值給result變量
result=${parameter:-word}
如果para變量為空,則word替代變量值,且返回其值
result=${parameter:=word}
如果para變量為空,word當(dāng)作stderr輸出,否則輸出變量值
用于設(shè)置變量為空導(dǎo)致錯(cuò)誤時(shí),返回的錯(cuò)誤信息
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文章
7401瀏覽量
129279 -
Shell
+關(guān)注
關(guān)注
1文章
375瀏覽量
25372 -
腳本
+關(guān)注
關(guān)注
1文章
409瀏覽量
29192
原文標(biāo)題:Shell腳本黑科技:5分鐘學(xué)會(huì)自動(dòng)化運(yùn)維,效率翻倍
文章出處:【微信號(hào):magedu-Linux,微信公眾號(hào):馬哥Linux運(yùn)維】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
Linux Shell腳本入門(mén)到實(shí)戰(zhàn)詳解
嵌入式Linux入門(mén)(五、Shell腳本編程上:認(rèn)識(shí)Shell腳本)
[Shell腳本專家指南]人民郵電出版社.掃描版
linux shell 腳本入門(mén)
嵌入式和物聯(lián)網(wǎng)的shell腳本學(xué)習(xí)指南之shell腳本入門(mén)免費(fèi)下載
shell腳本最簡(jiǎn)明的教程
109個(gè)實(shí)用shell腳本分享
shell腳本基礎(chǔ)知識(shí)
如何快速入門(mén)Shell腳本呢?
Linux Shell腳本經(jīng)典案例分享
Linux從零到精通:最簡(jiǎn)單的Shell腳本入門(mén)教程
Shell腳本入門(mén)指南
評(píng)論