国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

Linux_5_Shell腳本編程

這篇具有很好參考價(jià)值的文章主要介紹了Linux_5_Shell腳本編程。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問(wèn)。

1 基礎(chǔ)

1.1 程序組成

  • 程序:算法+數(shù)據(jù)結(jié)構(gòu)
  • 數(shù)據(jù):是程序的核心
  • 算法:處理數(shù)據(jù)的方式
  • 數(shù)據(jù)結(jié)構(gòu): 數(shù)據(jù)在計(jì)算機(jī)中的類型和組織方式

1.2 程序編程風(fēng)格

面向過(guò)程語(yǔ)言

  • 做一件事情,排出個(gè)步驟,第一步干什么,第二步干什么,如果出現(xiàn)情況A,做什么處理,如果出現(xiàn)了情況B,做什么處理
  • 問(wèn)題規(guī)模小,可以步驟化,按部就班處理
  • 以指令為中心,數(shù)據(jù)服務(wù)于指令
  • C,shell

面向?qū)ο笳Z(yǔ)言

  • 一種認(rèn)識(shí)世界、分析世界的方法論。將萬(wàn)事萬(wàn)物抽象為各種對(duì)象
  • 類是抽象的概念,是萬(wàn)事萬(wàn)物的抽象,是一類事物的共同特征的集合
  • 對(duì)象是類的具象,是一個(gè)實(shí)體
  • 問(wèn)題規(guī)模大,復(fù)雜系統(tǒng)
  • 以數(shù)據(jù)為中心,指令服務(wù)于數(shù)據(jù)
  • java,C#,python,golang等

1.3 編程語(yǔ)言

計(jì)算機(jī):運(yùn)行二進(jìn)制指令

編程語(yǔ)言:人與計(jì)算機(jī)之間交互的語(yǔ)言。分為兩種:低級(jí)語(yǔ)言和高級(jí)語(yǔ)言

  • 低級(jí)編程語(yǔ)言:

    • 機(jī)器:二進(jìn)制的0和1的序列,稱為機(jī)器指令。與自然語(yǔ)言差異太大,難懂、難寫(xiě)

    • 匯編:用一些助記符號(hào)替代機(jī)器指令,稱為匯編語(yǔ)言

      ? 如:ADDAB 將寄存器A的數(shù)與寄存器B的數(shù)相加得到的數(shù)放到寄存器A中

      ? 匯編語(yǔ)言寫(xiě)好的程序需要匯編程序轉(zhuǎn)換成機(jī)器指令

      ? 匯編語(yǔ)言稍微好理解,即機(jī)器指令對(duì)應(yīng)的助記符,助記符更接近自然語(yǔ)言

  • 高級(jí)編程語(yǔ)言:

    • 編譯:高級(jí)語(yǔ)言–>編譯器–>機(jī)器代碼文件->執(zhí)行,如: C,C++
    • 解釋:高級(jí)語(yǔ)言–>執(zhí)行–>解釋器–>機(jī)器代碼,如: shell,python,php,JavaScript,perl

編譯和解釋型語(yǔ)言
Linux_5_Shell腳本編程,Linux,linux,運(yùn)維
Linux_5_Shell腳本編程,Linux,linux,運(yùn)維

1.4 編程邏輯處理方式

Linux_5_Shell腳本編程,Linux,linux,運(yùn)維
Linux_5_Shell腳本編程,Linux,linux,運(yùn)維

三種處理邏輯

  • 順序執(zhí)行
  • 選擇執(zhí)行
  • 循環(huán)執(zhí)行

2 shell 腳本語(yǔ)言的基本結(jié)構(gòu)

2.1 shell腳本的用途

  • 自動(dòng)化常用命令
  • 執(zhí)行系統(tǒng)管理和故障排排除
  • 創(chuàng)建簡(jiǎn)單的應(yīng)用程序
  • 處理文本或文件

2.2 shell腳本基本結(jié)構(gòu)

shell腳本編程:是基于過(guò)程式、解釋執(zhí)行的語(yǔ)言

編程語(yǔ)言的基本結(jié)構(gòu):

  • ? 各種系統(tǒng)命令的組合
  • ? 數(shù)據(jù)存儲(chǔ):變量、數(shù)組
  • ? 表達(dá)式:a+b
  • ? 控制語(yǔ)句: if

shell腳本:包含一些命令或聲明,并符合一定格式的文本文件

格式要求:首行shebang機(jī)制
#!/bin/bash
#!/usr/bin/python
#!/usr/bin/perl

2.3 創(chuàng)建shell腳本過(guò)程

第一步:使用文本編輯器來(lái)創(chuàng)建文本文件

  • 第一行必須包括shell聲明序列: #!
  • 示例:
  • #!/bin/bash
  • 添加注釋,注釋以#開(kāi)頭

第二步:加執(zhí)行權(quán)限

  • 給予執(zhí)行權(quán)限,在命令行上指定腳本的絕對(duì)或相對(duì)路徑

第三步:運(yùn)行腳本

  • 直接運(yùn)行解釋器,將腳本作為解釋器程序的參數(shù)運(yùn)行
autocmd BufNewFile *.sh exec ":cal SetTitle()"
func SetTitle()
	if expand("%:e") == 'sh'
	call setline(1,"#!/bin/bash")
	call setline(2,"#")
	call setline(3,"#*****************************************************")
	call setline(4,"#Author:			minNexus")
	call setline(5,"#QQ:				1299575088")
	call setline(6,"#Date:				".strftime("%Y-%m-%d"))
	call setline(7,"#FileName:			.expand("%"))
	call setline(8,"#URL:				https://blog.csdn.net/qq_24472227?type=blog")		
	call setline(9,"#Description:		The test script")
	call setline(10,"#Copyright (C):	".strftime("%Y")," All rights reserved")
	call Setline(11,"#****************************************************")
	call setline(12,"")
	endif
endfunc
autocmd BufNewFile * normal G

2.4 腳本注釋規(guī)范

  1. 第一行一般為調(diào)用使用的語(yǔ)言

  2. 程序名,避免更改文件名為無(wú)法找到正確的文件

  3. 版本號(hào)

  4. 更改后的時(shí)間

  5. 作者相關(guān)信息

  6. 該程序的作用,及注意事項(xiàng)

  7. 最后是各版本的更新簡(jiǎn)要說(shuō)明

2.5 第一個(gè)腳本

[root@CentOS8 ~]#vim hello.sh
輸入echo hello world
[root@CentOS8 ~]#./hello.sh	執(zhí)行hello.sh
hello world

2.6 腳本調(diào)試

  • 語(yǔ)法錯(cuò)誤:導(dǎo)致后續(xù)命令不再執(zhí)行

  • 命令錯(cuò)誤:后續(xù)命令仍然執(zhí)行

  • 邏輯錯(cuò)誤

檢測(cè)腳本中的語(yǔ)法錯(cuò)誤,bash后加-n,提示出錯(cuò)行不一定準(zhǔn)確,不執(zhí)行
bash -n /path/to/some_script

一定程度上檢查邏輯出錯(cuò) 與 命令出錯(cuò),調(diào)試并執(zhí)行,加-x,逐行執(zhí)行并顯示
bash -x /path/to/some_script

注意:

  • bash ScriptName 開(kāi)啟一個(gè)子進(jìn)程,在里面執(zhí)行腳本
  • source ScriptName 在當(dāng)前進(jìn)程執(zhí)行腳本,不開(kāi)啟子進(jìn)程,如果在其中修改了變量,則修改了當(dāng)前shell的變量,不推薦使用,除非配置文件

2.7 變量

2.7.1 變量

變量表示命名的內(nèi)存空間,將數(shù)據(jù)放在內(nèi)存空間中,通過(guò)變量名引用,獲取數(shù)據(jù)

2.7.2 變量類型

類型:

  • 內(nèi)置變量,如: PS1,PATH,UID,HOSTNAME,PPID,$ , , ,?,BASHPID,HISTSIZE(使用$查看)
  • 用戶自定義變量

不同的變量存放的數(shù)據(jù)不同,決定了以下

  • 數(shù)據(jù)存儲(chǔ)方式
  • 參與的運(yùn)算
  • 表示的數(shù)據(jù)范圍

變量數(shù)據(jù)類型:

  • 字符
  • 數(shù)值:整型、浮點(diǎn)型 (bash不支持浮點(diǎn)型)

2.7.3 編程語(yǔ)言分類

靜態(tài)和動(dòng)態(tài)語(yǔ)言

  • 靜態(tài)編譯語(yǔ)言:使用變量前,先聲明變量類型,之后類型不能改變,在編譯時(shí)檢查,如:java,c
  • 動(dòng)態(tài)編譯語(yǔ)言:不用事先聲明,可隨時(shí)改變類型,如: bash,Python

強(qiáng)類型和弱類型語(yǔ)言

  • 強(qiáng)類型語(yǔ)言: 不同類型數(shù)據(jù)操作,必須經(jīng)過(guò)強(qiáng)制轉(zhuǎn)換才同一類型才能運(yùn)算,如java , c#,python

? 如:以下python代碼

print('magedu'+ 10) 提示出錯(cuò),不會(huì)自動(dòng)轉(zhuǎn)換類型
print('magedu'+str(10)) 結(jié)果為magedu10,需要顯示轉(zhuǎn)換類型
  • 弱類型語(yǔ)言:語(yǔ)言的運(yùn)行時(shí)會(huì)隱式類型轉(zhuǎn)換。無(wú)須指定類型,默認(rèn)均為字符型,參與運(yùn)算會(huì)自動(dòng)進(jìn)行隱式類型轉(zhuǎn)換;變量無(wú)須事先定義可直接調(diào)用

    如: bash ,php,javascript

2.7.4 shell中變量命名法則

不能使程序中的保留字:如: if,for

只能使用數(shù)字、字母及下劃線,且不能以數(shù)字開(kāi)頭,注意:不支持短橫線“.",和主機(jī)名相反

見(jiàn)名知義,用英文單詞命名,并體現(xiàn)出實(shí)際作用,不要用簡(jiǎn)寫(xiě),如: ATM

統(tǒng)一命名規(guī)則:駝峰命名法studentname,大駝峰StudentName ,小駝峰studentName

  • 變量名大寫(xiě):STUDENTNAME
  • 局部變量小寫(xiě)
  • 函數(shù)名小寫(xiě)

2.7.5 變量定義和引用

變量的生效范圍等標(biāo)準(zhǔn)劃分變量類型

  • 普通變量:生效范圍為當(dāng)前shel進(jìn)程;對(duì)當(dāng)前shell之外的其它shell進(jìn)程,包括當(dāng)前shell的子shell進(jìn)程均無(wú)效
  • 環(huán)境變量:生效范圍為當(dāng)前shell進(jìn)程及其子進(jìn)程
  • 本地變量:生效范圍為當(dāng)前shell進(jìn)程中某代碼片斷,通常指函數(shù)

變量賦值:

name='value'

value可以是以下多種形式

  • 直接字串: name=‘root’
  • 變量引用: name=“$USER”
  • 命令引用: name=COMMAND 或者 name=$(COMMAND)

注意:變量賦值臨時(shí)生效,終端退出將自動(dòng)刪除,不過(guò)為了安全起見(jiàn)最好使用完手動(dòng)刪除。腳本中的變量也隨腳本結(jié)束自動(dòng)刪除
變量引用:

$name
${name}

弱引用和強(qiáng)引用

"$name"	雙引號(hào),弱引用,其中的變量引用會(huì)被替換為變量值
'$name'	單引號(hào),強(qiáng)引用,其中的變量引用不會(huì)被替換為變量值,而保持原字符串

顯示已定義的所有變量

set

刪除變量

unset name

例:

1[root@CentOS8 ~]#ls	
f1.txt  f2.txt  f3.txt  issue.bak  passwd  scripts  test.img
[root@CentOS8 ~]#FILE=*	將當(dāng)前文件夾所有文件名保存至變量FILE中
[root@CentOS8 ~]#echo $FILE
f1.txt f2.txt f3.txt issue.bak passwd scripts test.img

2[root@CentOS8 ~]#FILE="i am $HOSTNAME" 將hostname的變量名存入變量FILE中
[root@CentOS8 ~]#echo $FILE
i am CentOS8.Joyce.person1

3[root@CentOS8 ~]#seq 10
1
2
3
4
5
6
7
8
9
10
[root@CentOS8 ~]#NUM=`seq 10`
[root@CentOS8 ~]#echo $NUM
1 2 3 4 5 6 7 8 9 10
[root@CentOS8 ~]#echo "$NUM" 加雙引號(hào)保留多行格式
1
2
3
4
5
6
7
8
9
10

2.7.6 環(huán)境變量

環(huán)境變量:可以使子進(jìn)程(包括子子進(jìn)程)繼承父進(jìn)程的變量,但是無(wú)法讓父進(jìn)程使用子進(jìn)程的變量
一旦子進(jìn)程修改從父進(jìn)程繼承的變量,新的值將傳遞給子子進(jìn)程
一般只在系統(tǒng)配置文件中使用,在腳本中較少使用

聲明環(huán)境變量 并賦值

export name=VALUE
declare -x name=VALUE

或分2步
name=VALUE
export name

變量引用

$name
${name}

例:

[root@CentOS8 ~]#NAME=joyce
[root@CentOS8 ~]#AGE=21
[root@CentOS8 ~]#echo $NAME$AGE
joyce21
[root@CentOS8 ~]#echo $NAME_$AGE
21
[root@CentOS8 ~]#echo ${NAME}_$AGE
joyce_21

顯示所有環(huán)境變量

env
printenv
export
declare -x

刪除變量:

unset name

bash內(nèi)建的環(huán)境變量

PATH
SHELL
USER
UID
HOME
PWD
SHLVL	當(dāng)前所在shell的深度,使用bash進(jìn)入下一shell(開(kāi)子進(jìn)程)后,深度+1,最低是1
LANG	當(dāng)前設(shè)置語(yǔ)言與編碼格式
MAIL	郵箱位置
HOSTNAME
HISTSIZE
_	下劃線,表示前一命令的最后一個(gè)參數(shù),前面記得加$

腳本:顯示系統(tǒng)信息

RED="\E[1;31m"
GREEN="\E[1;32m"
END="\E[0m"
echo -e	"\E[1;32m--------------------------------Host systeminfo------------------------------------$END"
echo -e	"HOSTNAME:		$RED`hostname`$END"
echo -e	"IPADDR:		$RED` ifconfig ens160|grep -Eo '([0-9]{1,3}\.){3}[0-9][1,3]' |head -n1`$END"
echo -e	"OSVERSION:		$RED`cat /etc/redhat-release`$END"
echo -e	"KERNEL:		$RED`uname -r`$END"
echo -e	"CPU:			$RED`lscpu|grep 'Model name'|tr -s ' '|cut -d : -f2`$END"
echo -e	"MEMORY:		$RED`free -h|grep Mem|tr -s ' ' : |cut -d : -f2`$END"
echo -e	"DISK:			$RED`lsblk |grep '^sd' |tr -s ' ' |cut -d " " -f4`$END"
echo -e	"\E[1;32m-----------------------------------------------------------------------------------$END"

2.7.7 只讀變量

只讀變量:只能聲明定義,但后續(xù)不能修改和刪除,即常量,退出終端自動(dòng)刪除

聲明只讀變量: 加-r

readonly name
declare -r name

查看只讀變量:

readonly [-p]
declare -r

2.7.8 位置變量

位置變量:在bash shell中內(nèi)置的變量,在腳本代碼中調(diào)用通過(guò)命令行傳遞給腳本的參數(shù)

$1,$2... 對(duì)應(yīng)第1個(gè)、第2個(gè)等參數(shù),shift [n]換位置
$0	命令本身,包括路徑,想只顯示名字可以寫(xiě)`basename $0`
$*	傳遞給腳本的所有參數(shù),全部參數(shù)合為一個(gè)字符串
$@	傳遞給腳本的所有參數(shù),每個(gè)參數(shù)為獨(dú)立字符串
$#	傳遞給腳本的參數(shù)的個(gè)數(shù)

注意: $@ $ 只在被雙引號(hào)包起來(lái)的時(shí)候才會(huì)有差異*

清空所有位置變量

set --

例:

[root@CentOS8 ~]#cat arg.sh 查看arg.sh文件
#!/bin/bash
#
#*****************************************************************************
#Author:                        minNexus
#QQ:                            1299575088
#Date:                          2023-07-25
#FileName:                      arg.sh
#URL:                           https://blog.csdn.net/qq_24472227?type=blog
#Description:                   The test script
#Copyright (C):                 2023 All rights reserved
#****************************************************************************

echo "lst arg is $l"
echo "2st arg is $2"
echo "3st arg is $3"
echo "10st arg is ${l0}"
echo "1lst arg is ${11}"

echo "The number of arg is $#"
echo "All args are $*"
echo "All args are $@"
echo "The scriptname is `basename $0`"

[root@CentOS8 ~]#bash arg.sh {a..z} 運(yùn)行腳本,加上a..z參數(shù)
lst arg is
2st arg is b
3st arg is c
10st arg is
1lst arg is k
The number of arg is 26
All args are a b c d e f g h i j k l m n o p q r s t u v w x y z
All args are a b c d e f g h i j k l m n o p q r s t u v w x y z
The scriptname is arg.sh

2.7.9 退出狀態(tài)碼變量

進(jìn)程執(zhí)行后,將使用變量 ? 保存狀態(tài)碼的相關(guān)數(shù)字,不同的值反應(yīng)成功或失敗,$?取值范例 0-255

  • $?的值為0 代表成功
  • $?的值是1到255 代表失敗

例:

[root@CentOS8 ~]#curl www.google.com &> /dev/null
[root@CentOS8 ~]#echo $?
7

用戶可以在腳本中使用以下命令自定義退出狀態(tài)碼

exit [n]

注意:

  • 腳本中一旦遇到exit命令,腳本會(huì)立即終止,終止退出狀態(tài)取決于exit命令后面的數(shù)字
  • 如果未給腳本指定退出狀態(tài)碼,整個(gè)腳本的退出狀態(tài)碼取決于腳本中執(zhí)行的最后一條命令的狀態(tài)碼

2.7.10 展開(kāi)命令行

展開(kāi)命令執(zhí)行順序:

把命令行分成單個(gè)命令詞
展開(kāi)別名
展開(kāi)大括號(hào)的聲明{}
展開(kāi)波浪符聲明 ~
命令替換$()和``
再次把命令行分成命令詞
展開(kāi)文件通配* ? [abc]等等
準(zhǔn)備I/0重導(dǎo)向 <、>
運(yùn)行命令
防止擴(kuò)展:
反斜線(\)會(huì)使隨后的字符按原意解釋

加引號(hào)來(lái)防止擴(kuò)展:
單引號(hào)('')-防止所有擴(kuò)展
雙引號(hào) ("")也可防止擴(kuò)展,但是以下情況例外: $(美元符號(hào))

變量擴(kuò)展:
``	反引號(hào),命令替換
\	反斜線,禁止單個(gè)字符擴(kuò)展
!	嘆號(hào),歷史命令替換

2.7.11 腳本安全和 set 命令

**set命令:**可以用來(lái)定制shell環(huán)境

$- 變量
h	hashal,打開(kāi)洗項(xiàng)后,Shell會(huì)將命令所在的路徑hash下來(lái),避免每次都要查詢。通過(guò)set +h將h洗項(xiàng)關(guān)閉
i	interactive-comments,包含這個(gè)選項(xiàng)說(shuō)明當(dāng)前的 shel 是一個(gè)交式的 shel。所謂的交式shell,在腳本中i選項(xiàng)是關(guān)閉的
m	monitor,打開(kāi)監(jiān)控模式,就可以通過(guò)Job control來(lái)控制進(jìn)程的停止、繼續(xù),后臺(tái)或者前臺(tái)執(zhí)行等
B	braceexpand,大括號(hào){}擴(kuò)展,set +B關(guān)閉{}的功能
H	history,H選項(xiàng)打開(kāi),可以展開(kāi)歷史列表中的命令,可以通過(guò)!感嘆號(hào)來(lái)完成,例如“!"返回上最近的一個(gè)歷史命令,“!n”返回第 n個(gè)歷史命令

set 命今實(shí)現(xiàn)腳本安全	推薦打開(kāi)-eu
-u	在擴(kuò)展一個(gè)沒(méi)有設(shè)置的變量時(shí),顯示錯(cuò)誤信息,等同set -o nounset,避免出現(xiàn)刪除整個(gè)目錄
-e	如果一個(gè)命令返回一個(gè)非0退出狀態(tài)值(失敗)就退出,等同set -o errexit
-o	option 顯示,打開(kāi)或者關(guān)閉選項(xiàng)
	顯示選項(xiàng)	set-o
	打開(kāi)選項(xiàng)	set -o選項(xiàng)
	關(guān)閉選項(xiàng)	set +o選項(xiàng)
-x	當(dāng)執(zhí)行命令時(shí),打印命令及其參數(shù),類似bash -x

2.8 格式化輸出 printf

格式

printf "指定的格式" "文本1" "文本2"...
常用格式替換符
%s		字符串
%f		浮點(diǎn)格式
%b		相對(duì)應(yīng)的參數(shù)中包含轉(zhuǎn)義字符時(shí),可以使用此替換符進(jìn)行替換,對(duì)應(yīng)的轉(zhuǎn)義字符會(huì)被轉(zhuǎn)義
%c		ASCII字符,即顯示對(duì)應(yīng)參數(shù)的第一個(gè)字符
%d,%i	十進(jìn)制整數(shù)
%o		八進(jìn)制值
%u		不帶正負(fù)號(hào)的十進(jìn)制值
%x		十六進(jìn)制值 (a-f)
%X		十六進(jìn)制值 (A-F)
%%		

說(shuō)明:%s中的數(shù)字代表此替換符中的輸出字符寬度,不足補(bǔ)空格,默認(rèn)是右對(duì)齊,%-10s表示10個(gè)字符寬,- 表示左對(duì)齊

常用轉(zhuǎn)義字符:

\a	警告字符,通常為ASCII的BEL字符
\b	后退
\f	換頁(yè)
\n	換行
\r	回車
\t	水平制表符
\v	垂直制表符
\	表示\本身

例:

[root@CentOS8 ~]#printf "(%.3f)\n" 1 2 3
(1.000)
(2.000)
(3.000)

[root@CentOS8 ~]#printf "%s\n%s" 1 2 3 4;echo
1
23
4

2.9 算術(shù)運(yùn)算

shell 支持算術(shù)運(yùn)算,但只支持整數(shù),不支持小數(shù)
bash中的算術(shù)運(yùn)算:

+
-
*
/
%	取模,即取余數(shù),%5的結(jié)果在0-4
**	乘方

乘法符號(hào)有些場(chǎng)景中需要轉(zhuǎn)義
實(shí)現(xiàn)算術(shù)運(yùn)算:

let var=算術(shù)表達(dá)式
var=$[算術(shù)表達(dá)式]
var=$((算術(shù)表達(dá)式))
var=$(expr argl arg2 arg3 ...)	注意:expr里*可能被當(dāng)作通配符,乘法要用\*
declare -i var = 數(shù)值
echo'算術(shù)表達(dá)式'|bc

例:

[root@CentOS8 ~]#echo -e "\E[1;$[RANDOM%7+31]mhello\e[0m"	打印隨機(jī)顏色的hello,顏色編號(hào)31-37
hello

[root@CentOS8 ~]#expr 99 \* 3	
297

[root@CentOS8 ~]#echo "scale=3;3/7"|bc
.428

內(nèi)建的隨機(jī)數(shù)生成器變量
$RANDOM 取值范圍 0-32767

增強(qiáng)型賦值:

+=	i+=10	相當(dāng)于 i=i+10
-=	i-=j	相當(dāng)于 i=i-j
*=
/=
%=
++	i++,++i		相當(dāng)于 i=i+1
--	i--,--i		相當(dāng)于 i=i-1

2.10 邏輯運(yùn)算

true false
 1     0

與:&		與0為0,與1保留
	1與1=1
	1與0=0
	0與1=0
	0與0=0
或:|		同0為0
	1或1=1
	1或0=1
	0或1=1
	0或0=0
非:!
	!1 =0	! true
	!0 =1 	! false
異或:^	異或的兩個(gè)值,相同為,假0;不同為真,非0。
	1^1=0
	1^0=1
	0^1=1
	0^0=0
		兩個(gè)數(shù)字異或,將結(jié)果與任意一個(gè)數(shù)字異或,結(jié)果是另一數(shù)字
	12^8=4
	8^4=12
	12^4=8

例:

[root@CentOS8 ~]#i=i=10;j=20;echo i=$[i^(i^j)] j=$[j^(i^j)]	使用異或交換i和j的值
i=20 j=10
[root@CentOS8 ~]#i=10;j=20;i=$[i^j];j=$[i^j];i=$[i^j];echo i=$i,j=$j
i=20,j=10

短路運(yùn)算

短路與
CMD1 短路與 CMD2

  • 第一個(gè)CMD1結(jié)果為0(假),總的結(jié)果必定為0,因此不需要執(zhí)行CMD2
  • 第一個(gè)CMD1結(jié)果為1(真),第二個(gè)CMD2必須要參與運(yùn)算,才能得到最終的結(jié)果

短路或
CMD1 短路或CMD2

  • 第一個(gè)CMD1結(jié)果為1(真),總的結(jié)果必定為1,因此不需要執(zhí)行CMD2
  • 第一個(gè)CMD1結(jié)果為0(假),第二個(gè)CMD2必須要參與運(yùn)算,才能得到最終的結(jié)果

2.11 條件測(cè)試命令

條件測(cè)試:判斷某需求是否滿足,需要由測(cè)試機(jī)制來(lái)實(shí)現(xiàn),專用的測(cè)試表達(dá)式需要由測(cè)試命令輔助完成測(cè)試過(guò)程,實(shí)現(xiàn)評(píng)估布爾聲明,以便用在條件性環(huán)境下進(jìn)行執(zhí)行

  • 若真,則狀態(tài)碼變量 $? 返回0
  • 若假,則狀態(tài)碼變量 $? 返回1

條件測(cè)試命令

test EXPRESSION	 等價(jià)于  [ EXPRESSION ]	推薦使用[ ] 
[[ EXPRESSION ]]

注意:EXPRESSION前后必須有空白字符

2.11.1 變量測(cè)試

-v VAR	變量VAR是否設(shè)置,即是否存在
-R VAR	變量VAR是否設(shè)置并引用

示例:判斷NAME變量是否定義

[root@CentOS8 ~]#[ -v name ] 或 test -v NAME
[root@CentOS8 ~]#echo $?
1

2.11.2 數(shù)值測(cè)試

-eq 是否等于
-ne 是否不等于
-gt 是否大于
-ge 是否大于等于
-lt 是否小于
-le 是否小于等于

例:

[root@CentOS8 ~]#x=33
[root@CentOS8 ~]#y=44
[root@CentOS8 ~]#[ $x -gt $y ]	必須假$
[root@CentOS8 ~]#echo $?
1
[root@CentOS8 ~]#[ $x -lt $y ]
[root@CentOS8 ~]#echo $?
0

2.11.3 字符串測(cè)試

-z "STRING"	字符串是否為空,未定義或空為真,不空為假
-n "STRING"	字符串是否不空,不空為真,空為假

=	是否等于
!=	是否不等于

? ascii碼是否大于ascii碼

<	是否小于
==	左側(cè)字符串是否和右側(cè)的PATTERN相同
注意:此表達(dá)式用于[[ ]]中,PATTERN為通配符
=~	左側(cè)字符串是否能夠被右側(cè)的正則表達(dá)式的PATTERN所匹配

注意: 此表達(dá)式用于[[ ]]中;擴(kuò)展的正則表達(dá)式

  • 即只在正則表達(dá)式才用雙中括號(hào)[[]],其他都用[]
  • 且在[[ == ]] 右側(cè)的*,單列則表示通配符,只作為字符需要加""或\轉(zhuǎn)義
  • 字符串最好兩邊加"",否則可能出現(xiàn)問(wèn)題
[root@CentOS8 ~]#name="hello babe"
[root@CentOS8 ~]#[ $name ]
-bash: [: hello: unary operator expected
[root@CentOS8 ~]#[ "$name" ]
[root@CentOS8 ~]#echo $?
0

例:

[root@CentOS8 ~]#title1=ceo
[root@CentOS8 ~]#title1=cto
[root@CentOS8 ~]#[ $title1 = $title2 ] 字符串之間必須加空格 ,不加空格則成賦值
[root@CentOS8 ~]#echo $?
1

2通配符
[root@CentOS8 ~]#FILE=test.log	
[root@CentOS8 ~]#[[ "$FILE == *.log" ]]
[root@CentOS8 ~]#echo $?
0

3正則表達(dá)式
[root@CentOS8 ~]#FILE=test.log
[root@CentOS8 ~]#[[ "$FILE" =~ \.log$ ]]
[root@CentOS8 ~]#echo $?
0

[root@CentOS8 ~]#IP=1.2.3.444	判斷ip地址是否合法(在255.255.255.255之間)
[root@CentOS8 ~]#[[ $IP =~ ^(([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$ ]]
[root@CentOS8 ~]#echo $?
1
[root@CentOS8 ~]#IP=1.2.3.4
[root@CentOS8 ~]#echo $?
0

2.11.4 文件測(cè)試

存在性測(cè)試

-a FILE	同 -e
-e FILE 文件存在性測(cè)試,存在為真,否則為假
-b FILE 是否存在且為塊設(shè)備文件
-C FILE	是否存在且為字符設(shè)備文件
-d FILE 是否存在且為目錄文件
-f FILE	是否存在且為普通文件,判斷軟鏈接則判斷軟鏈接指定的文件
-h FILE 或 -L FILE: 存在且為符號(hào)鏈接文件
-p FILE 是否存在且為命名管道文件
-S FILE	是否存在且為套接字文件

例:

[root@CentOS8 ~]#[[ -c  /dev/zero  ]]	判斷是否為字符文件
[root@CentOS8 ~]#echo $?
0

文件權(quán)限測(cè)試.

-r FILE 是否存在且可讀
-W FILE 是否存在且可寫(xiě)
-X FILE 是否存在且可執(zhí)行
-u FILE 是否存在且擁有suid權(quán)限
-g FILE 是否存在且擁有sgid權(quán)限
-k FILE 是否存在且擁有sticky權(quán)限

例:

[root@CentOS8 ~]# [[ -x CHOOK_RABBIT.sh ]] 判斷是否有執(zhí)行權(quán)限
[root@CentOS8 ~]#echo $?
0
[root@CentOS8 ~]#chmod 0 CHOOK_RABBIT.sh   去除所有權(quán)限
[root@CentOS8 ~]# [[ -x CHOOK_RABBIT.sh ]] 判斷是否有執(zhí)行權(quán)限
[root@CentOS8 ~]#echo $?
1

[root@CentOS8 ~]# [[ -r CHOOK_RABBIT.sh ]] 判斷是否有可讀權(quán)限,因?yàn)槲覀兪莚oot,所有仍然可以讀
[root@CentOS8 ~]#echo $?
0
[root@CentOS8 ~]# [[ -w CHOOK_RABBIT.sh ]] 判斷是否有寫(xiě)入權(quán)限,因?yàn)槲覀兪莚oot,所有仍然可以寫(xiě)
[root@CentOS8 ~]#echo $?
0

文件屬性測(cè)試

-S FILE	是否存在且非空
-t fd	fd 文件描述符是否在某終端已經(jīng)打開(kāi)
-N FILE 文件自從上一次被讀取之后是否被修改過(guò)
-O FILE 當(dāng)前有效用戶是否為文件屬主
-G FILE 當(dāng)前有效用戶是否為文件屬組
FILE1 -ef FILE2	: FILE1是否是FILE2的硬鏈接
FILE1 -nt FILE2 : FILE1是否新于FILE2(mtime)
FILE1 -ot FILE2 : FILE1是否舊于FILE2

2.12 關(guān)于()和{}

(CMD1;CMD2;...)	都可以批量執(zhí)行多個(gè)命令
{ CMD1;CMD2;...; }最后加;,{ }內(nèi)前后加空格
  • ()會(huì)開(kāi)啟子shell,繼承父進(jìn)程的變量。list中變量賦值及內(nèi)部命令執(zhí)行后,不影響后續(xù)的環(huán)境。幫助參看:man bash 搜索(list)

  • {;}不會(huì)啟子shell,在當(dāng)前shell中運(yùn)行,會(huì)影響當(dāng)前shell環(huán)境,幫助參看:man bash 搜索{list;}

例:

[root@CentOS8 ~]#name=babe;(echo $name;name=hello;echo $name);echo $name	使用()
babe
hello
babe
[root@CentOS8 ~]#name=babe;{ echo $name;name=hello;echo $name; };echo $name	使用{}
babe
hello
hello

2.13 組合測(cè)試條件

2.13.1 方法 1 []

EXPRESSION1 -a EXPRESSION2	并且,EXPRESSION1和EXPRESSION2都是真,結(jié)果才為真
EXPRESSION1 -o EXPRESSION2	或者,EXPRESSION1和EXPRESSION2只要有一個(gè)真,結(jié)果就為真
[ ! EXPRESSION ]![ exp ]			取反

說(shuō)明: -a和-0 需要使用測(cè)試命令進(jìn)行,[[]]不支持

2.13.2 方法 2 [[]]

COMMAND1 && COMMAND2	#并且,短路與,代表?xiàng)l件性的AND	THEN

如果COMMAND1 成功,將執(zhí)行COMMAND2,否則,將不執(zhí)行COMMAND2

COMMAND1 || COMMAND2	#或者,短路或,代表?xiàng)l件性的OR	ELSE

如果COMMAND1 成功,將不執(zhí)行COMMAND2否則,將執(zhí)行COMMAND2

!COMMAND	非,取反

例:

[root@CentOS8 ~]#NAME=joycee;id $NAME &> /dev/null && echo "$NAME is exist" || echo "$NAME is not exist"
joycee is not exist

[root@CentOS8 ~]#NANAME=joycee;id $NAME &> /dev/null && echo "$NAME is exist" || (useradd $NAME;echo $NAME is created)
joycee is created

注意:&& 如果和 || 混用,則&& 要放前,|| 放后

2.13 使用read命今來(lái)接受輸入

使用read來(lái)把輸入值分配給一個(gè)或多個(gè)shell變量,read從標(biāo)準(zhǔn)輸入中讀取值,給每個(gè)單詞分配一個(gè)變量,所有剩余單詞都被分配給最后一個(gè)變量
格式

read [options] [name ...]

常見(jiàn)選項(xiàng):

-p	指定要顯示的提示
-s	靜默輸入,一般用于密碼
-n	N 指定輸入的字符長(zhǎng)度N
-d	'字符',輸入結(jié)束符
-t	N TIMEOUT為N秒
[root@CentOS8 ~]#read
joyce
[root@CentOS8 ~]#echo $REPLY
joyce

[root@CentOS8 ~]#read NAME TITLE
joyce babe
[root@CentOS8 ~]#echo $NAME $TITLE
joyce babe

[root@CentOS8 ~]#read -p "are u ok?" ANSWER
are u ok?not bad
[root@CentOS8 ~]#echo $ANSWER
not bad

[root@CentOS8 ~]#echo 1 2 > test.txt	重定向
[root@CentOS8 ~]#read a b < test.txt;echo $a; echo $b
1
2

注意:

[root@CentOS8 ~]#echo 1 2 | read a b | echo $a $b
1 2
[root@CentOS8 ~]#echo 1 2 | (read a b; echo $a $b)
1 2
[root@CentOS8 ~]#echo 1 2 | read a b; echo $a $b	管道里,如果不加括號(hào)或|,則中間和后面是兩個(gè)獨(dú)立的shell,因此二者的ab不等
1 2

3 bash的配置文件

bash shell的配置文件很多,可以分成下面類別

3.1 按生效范圍劃分兩類

全局配置

/etc/profile
/etc/profile.d/*.sh
/etc/bashrc

個(gè)人配置:

~/.bash_profile
~/.bashrc

3.2 shell登錄兩種方式分類

3.2.1 交互式登錄

  • 直接通過(guò)終端輸入賬號(hào)密碼登錄
  • 使用su - UserName切換用戶

配置文件執(zhí)行順序:

/etc/profile --> /etc/profile.d/*,sh --> ~/.bash_profile --> ~/.bashrc --> /etc/bashrc

3.2.2 非交互式登錄

su UserName

圖形界面下打開(kāi)的終端
執(zhí)行腳本
任何其它的bash實(shí)例

執(zhí)行順序:

/etc/profile.d/*.sh --> /etc/bashrc -->~/.bashrc

3.3 按功能劃分分類

profile類和bashrc類

3.3.1 profile類

profile類為交互式登錄的shell提供配置

全局: /etc/profile,/etc/profile.d/*.sh
個(gè)人:~/.bash_profile

作用:

  1. 用于定義環(huán)境變量
  2. 運(yùn)行命令或腳本

3.3.2 Bashrc類

bashrc類:為非交互式和交互式登錄的shell提供配置

全局: /etc/bashrc
個(gè)人:~/.bashrc

作用:

  1. 定義命令別名和函數(shù)
  2. 定義本地變量

3.4 編輯配置文件生效

修改profile和bashrc文件后有生效兩種方法

  1. 重新啟動(dòng)shell進(jìn)程
  2. source 或 . 配置文件

3.5 Bash 退出任務(wù)

保存在~/.bash_logout文件中 (用戶),在退出登錄shell時(shí)運(yùn)行

功能

  • ? 創(chuàng)建自動(dòng)備份
  • ? 清除臨時(shí)文件

4 流程控制

4.1 條件選擇

條件判斷:

if
case
&& ||

4.1.1 選擇執(zhí)行 if 語(yǔ)句

格式:

if CMDs; then CMDs;[ elif CMDs; then CMDs; ]... [ else CMDs; ] fi

單分支:

if 判斷條件;then
	條件為真的分支代碼
fi

雙分支:

if 判斷條件; then
	條件為真的分支代碼
e1se
	條件為假的分支代碼
fi

多分支:

if 判斷條件1; then
	條件1為真的分支代碼
elif 判斷條件2; then
	條件2為真的分支代碼
... 
e1se
	以上條件都為假的分支代碼
fi

說(shuō)明:

  • 多個(gè)條件時(shí),逐個(gè)條件進(jìn)行判斷,第一次遇為“真”條件時(shí),執(zhí)行其分支,而后結(jié)束整個(gè)if語(yǔ)句
  • if 語(yǔ)句可嵌套

4.1.2 條件判斷 case 語(yǔ)句

格式:

case WORD in [PATTERN [| PATTERN]...) CMDs ;;]...esac

此處PATTERN指通配符的模式

case 變量引用 in
PAT1)
	分支1
	;;
PAT2)
	分支2
	;;
...
*)
	默認(rèn)分支
	;;
esac

case支持glob風(fēng)格的通配符:

*	任意長(zhǎng)度任意字符
?	任意單個(gè)字符
[]	指定范圍內(nèi)的任意單個(gè)字符
|	或,如 a或b
  1. G R E E N " 清理日志 " GREEN"清理日志" GREEN"清理日志"END
    ;;

4.2 循環(huán)

4.2.1 循環(huán)執(zhí)行介紹

Linux_5_Shell腳本編程,Linux,linux,運(yùn)維

將某代碼段重復(fù)運(yùn)行多次,通常有進(jìn)入循環(huán)的條件和退出循環(huán)的條件

重復(fù)運(yùn)行次數(shù)

  • 循環(huán)次數(shù)事先已知
  • 循環(huán)次數(shù)事先未知

常見(jiàn)的循環(huán)的命令:for,while,until

Linux_5_Shell腳本編程,Linux,linux,運(yùn)維

4.2.2 for循環(huán)

4.2.2.1 格式1
for NAME [in WORDS ...] ; do COMMANDS; done
						(WORD之間使用空白符(空格、Tab鍵、回車)分割)for	變量名 in 列表;do
		循環(huán)體
donefor	變量名 in 列表
do
		循環(huán)體
done

執(zhí)行機(jī)制:依次將列表中的元素賦值給“變量名”, 每次賦值后即執(zhí)行一次循環(huán)體;直到列表中的元素耗盡,循環(huán)結(jié)束

for循環(huán)列表生成方式:

  • 直接給出列表
  • 整數(shù)列表
{start..end}
$(seq [start [step]] end)
  • 返回列表的命令:
$(COMMAND)
  • 使用glob,如:*.sh
  • 變量引用,如:$@,$#,$*等位置參數(shù) ( ? 將變量視為單個(gè), *將變量視為單個(gè), ?將變量視為單個(gè),@將變量視為整體)

死循環(huán):

for((;;)) ; do CMDs;done

例:

[root@CentOS8 ~]#for i in {001..8..2};do echo $i;  done
001
003
005
007
[root@CentOS8 ~]#for i in `seq 5`;do echo $i;  done
1
2
3
4
5
[root@CentOS8 ~]#for i in $(seq 5);do echo $i;  done
1
2
3
4
5

例:計(jì)算1+2+3+…+100的和

[root@CentOS8 ~]#seq -s+ 100|bc
5050[root@CentOS8 ~]#sum=0;for i in {1..100};do let sum+=i;done;echo $sum
5050

例:

[root@CentOS8 scripts]#cat sum.sh
#!/bin/bash

sum=0
for i in $@ ;do
        let sum+=i
done

echo $sum

[root@CentOS8 scripts]#chmod +x sum.sh
[root@CentOS8 scripts]#./sum.sh 1  3 4 5 6
19

例:九九乘法表的實(shí)現(xiàn)

[root@CentOS8 scripts]#cat ./9x9.sh
#!/bin/bash

for j in {1..9};do
        for i in `seq $j`;do
                echo -e "${i}x$j=$((i*j))\t\c"
        done
        echo
done
[root@CentOS8 scripts]#./9x9.sh
1x1=1
1x2=2   2x2=4
1x3=3   2x3=6   3x3=9
1x4=4   2x4=8   3x4=12  4x4=16
1x5=5   2x5=10  3x5=15  4x5=20  5x5=25
1x6=6   2x6=12  3x6=18  4x6=24  5x6=30  6x6=36
1x7=7   2x7=14  3x7=21  4x7=28  5x7=35  6x7=42  7x7=49
1x8=8   2x8=16  3x8=24  4x8=32  5x8=40  6x8=48  7x8=56  8x8=64
1x9=9   2x9=18  3x9=27  4x9=36  5x9=45  6x9=54  7x9=63  8x9=72  9x9=81

面試題:要求將目錄YYYY-MM-DD/中所有文件,移動(dòng)到Y(jié)YYY-MM/DD/下

#1 yyyy-mm-dd10.sh ,準(zhǔn)備數(shù)據(jù)
#創(chuàng)建YYYY-MM-DD,當(dāng)前日期一年前365天到目前共365個(gè)目錄,里面有10個(gè)文件,$RANDOM.Tog

[root@centos8 ~]#cat for_dir20.sh
#!/bin/bash
for i in {1..365};do
    DIR=`date -d "-$i day" +%F`
    mkdir /data/test/$DIR
    cd /data/test/$DIR
    for n in {1..10};do
    		touch $RANDOM.log
    done
done

#2 移動(dòng)到Y(jié)YYY-MM/DD/下
[root@centos8 ~]#cat for_mv20.sh
#!/bin/bash
#
DIR=/data/test
cd $DIR
for DIR in *;do
    YYYY_MM=`echo $DIR |cut -d"-" -f1,2`	#將年月和日期拆分成2部分,這里是年月
    DD=`echo $DIR | cut -d"-" -f3`			  #這里是日期
    [ -d $YYYY_MM/$DD ] || mkdir -p $YYYY_MM/$DD &> /dev/null
    mv $DIR/*	$YYYY_MM/$DD
done

面試題:掃描一個(gè)網(wǎng)段:10.0.0.0/24,判斷此網(wǎng)段中主機(jī)在線狀態(tài),將在線的主機(jī)的IP打印出來(lái)

NET=10.0.0
for ID in {1..254};do
        {
        ping -c1 -W1 $NET.$ID &> /dev/null && echo $NET.$ID is up  || echo $NET.$ID is down
        }&      #實(shí)現(xiàn)并行
done
wait	#默認(rèn)并行不會(huì)自動(dòng)退出,加上wait使其自動(dòng)執(zhí)行下一個(gè)命令
4.2.2.2 格式2

雙小括號(hào)方法,即((…))格式,也可以用于算術(shù)運(yùn)算,雙小括號(hào)方法也可以使bash Shell實(shí)現(xiàn)C語(yǔ)言風(fēng)格的變量操作

|=10;((l++))

Linux_5_Shell腳本編程,Linux,linux,運(yùn)維

for ((控制變量初始化;條件判斷表達(dá)式;控制變量的修正表達(dá)式))
do
		循環(huán)體
done

說(shuō)明:

  • 控制變量初始化:僅在運(yùn)行到循環(huán)代碼段時(shí)執(zhí)行一次
  • 控制變量的修正表達(dá)式:每輪循環(huán)結(jié)束會(huì)先進(jìn)行控制變量修正運(yùn)算,而后再做條件判斷

例:實(shí)現(xiàn)1累加到100

for ((sum=0;i<=100;i++));do
        let sum+=i
done
echo $sum

例:九九乘法表的實(shí)現(xiàn)_2

for ((i=1;i<10;i++));do
        for((j=1;j<=i;j++));do
                echo -e "${j}x$i=$((j*i))\t\c"
        done
        echo
done

例:實(shí)現(xiàn)國(guó)際象棋的棋盤(pán)(較垃圾)

for ((i=1;i<=8;i++));do
        if((i%2));then
                for((x=0;x<4;x++));do
                        for ((j=0;j<8;j++));do
                                if ((j%2));then
                                        echo -e '\E[47m        \E[0m\c' ;
                                else
                                        echo -e '\E[40m        \E[0m\c' ;
                                fi
                        done
                        echo
                done
        else
                for((x=0;x<4;x++));do
                        for ((j=0;j<8;j++));do
                        if ((j%2));then
                        echo -e '\E[40m        \E[0m\c' ;
                else
                        echo -e '\E[47m        \E[0m\c' ;
                fi
                done
                        echo
                done
        fi
done

Linux_5_Shell腳本編程,Linux,linux,運(yùn)維

例:實(shí)現(xiàn)三角形

for((i=1;i<=10;i++));do
        #for((z=0;z<=10-i;z++));do
        for((z=10;z-i>0;z--));do
                echo -e ' \c';
        done
                for((j=1;j<=2*i-1;j++));do
                        echo -e '*\c'
                done
                echo
done

Linux_5_Shell腳本編程,Linux,linux,運(yùn)維

例:加入?yún)?shù)實(shí)現(xiàn)三角形

read -p "請(qǐng)輸入三角形的行數(shù):" line
for((i=1;i<=$line;i++));do
        #for((z=0;z<=10-i;z++));do
        for((z=$line;z-i>0;z--));do
                echo -e ' \c';
        done
                for((j=1;j<=2*i-1;j++));do
                        echo -e '*\c'
                done
                echo
done

Linux_5_Shell腳本編程,Linux,linux,運(yùn)維

4.2.3 while循環(huán)

格式:

while COMMANDs; do COMMANDS; done

while CONDITION; do
		循環(huán)體
done

說(shuō)明:

CONDITION:循環(huán)控制條件,進(jìn)入循環(huán)之前,先做一次判斷,每一次循環(huán)之后會(huì)再次做判斷;條件為“true",則執(zhí)行一次循環(huán),直到條件測(cè)試狀態(tài)為“false"終止循環(huán),因此:CONDTION一般應(yīng)該有循環(huán)控制變量,而此變量的值會(huì)在循環(huán)體不斷地被修正

  • 進(jìn)入條件: CONDITION為true
  • 退出條件: CONDITION為false

死循環(huán):

#方法1
while true; do
		循環(huán)體
done

#方法2
while :; do
		循環(huán)體
done

范例:使用while實(shí)現(xiàn)磁盤(pán)報(bào)警

WARNING=10	#閾值
while : ;do
        USE=`df | sed -rn '/^\/dev\/sd/s#.* ([0-9]+)%.*#\1#p' |sort -nr | head -n1`
        if [ $USE -gt $WARNING ] ; then
                echo DISK will be full from `hostname -I` | mail -s "Disk Warning" 1299575088@qq.com
        fi
        sleep 10	#10秒循環(huán)一次
done

例:死循環(huán)

[root@CentOS8 scripts]#while :;do echo ok ;sleep 1 ;done
ok
ok
ok
ok
ok

4.2.4 until循環(huán)

格式:

until COMMANDS; do COMMANDS; done

until CONDITION; do
	循環(huán)體
done

說(shuō)明:

  • 進(jìn)入條件:CONDITION為false
  • 退出條件:CONDITION為true

死循環(huán)

until false; do
	循環(huán)體
done

4.2.4 循環(huán)控制語(yǔ)句 continue

continue[N]:提前結(jié)束第N層的本輪循環(huán),而直接進(jìn)入下一輪判斷,最內(nèi)層為第1層

格式:

while CONDITION1; do
	CMD1
	...
	if CONDITION2; then
		continue
		CMDn
		...
done

例:

#1
for((i=0;i<10;i++));do
        for((j=0;j<10;j++));do
                [ $j -eq 5 ] && continue 1	#1可以不寫(xiě),代表終止該層循環(huán)的本次循環(huán)
                echo $j
        done
        echo -----------------
done
[root@CentOS8 scripts]#bash continue_for_1.sh
0
1
2
3
4
6
7
8
9
-----------------
0
1
2
3
4
6
7
8
9
-----------------
0
1
2
3
4
6
7
8
9
-----------------
0
1
2
3
4
6
7
8
9
-----------------
0
1
2
3
4
6
7
8
9
-----------------
0
1
2
3
4
6
7
8
9
-----------------
0
1
2
3
4
6
7
8
9
-----------------
0
1
2
3
4
6
7
8
9
-----------------
0
1
2
3
4
6
7
8
9
-----------------
0
1
2
3
4
6
7
8
9
-----------------
#2
for((i=0;i<10;i++));do
        for((j=0;j<10;j++));do
                [ $j -eq 5 ] && continue 2	#2代表終止外層循環(huán)的本次循環(huán),使外層循環(huán)進(jìn)入下次循環(huán)
                echo $j
        done
        echo -----------------
done
[root@CentOS8 scripts]#bash continue_for_1.sh
0
1
2
3
4
0
1
2
3
4
0
1
2
3
4
0
1
2
3
4
0
1
2
3
4
0
1
2
3
4
0
1
2
3
4
0
1
2
3
4
0
1
2
3
4
0
1
2
3
4

4.2.5 循環(huán)控制語(yǔ)句 break

break [N]:提前結(jié)束第N層整個(gè)循環(huán),最內(nèi)層為第1層
格式:

while CONDITION1; do
	CMD1
	...
	if CONDITION2; then
		break
	fi
	CMDn

例:

#1
for((i=0;i<10;i++));do
        for((j=0;j<10;j++));do
                [ $j -eq 5 ] && break 1 #1可以不寫(xiě),表示結(jié)束內(nèi)層循環(huán),使外層循環(huán)進(jìn)入下一輪
                echo $j
        done
        echo -----------------
done
[root@CentOS8 scripts]#bash continue_for_1.sh
0
1
2
3
4
-----------------
0
1
2
3
4
-----------------
0
1
2
3
4
-----------------
0
1
2
3
4
-----------------
0
1
2
3
4
-----------------
0
1
2
3
4
-----------------
0
1
2
3
4
-----------------
0
1
2
3
4
-----------------
0
1
2
3
4
-----------------
0
1
2
3
4
-----------------

#2
for((i=0;i<10;i++));do
        for((j=0;j<10;j++));do
                [ $j -eq 5 ] && break 2 #2表示結(jié)束外層循環(huán),即結(jié)束所有循環(huán)
                echo $j
        done
        echo -----------------
done
[root@CentOS8 scripts]#bash continue_for_1.sh
0
1
2
3
4

例:菜品選擇

sum=0
COLOR1='echo -e \033[1;31m'
COLOR2='echo -e \033[1;32m'
END="\033[0m"

while :;do
        echo -e "\033[33;1m\c"
        cat <<-EOF
1)2)3)4)5)6)肉
        EOF
        echo -e "\033[0m"

read -p "請(qǐng)選擇菜品:" MENU
case $MENU in
1|4)
        $COLOR1'菜價(jià):$10'$END
        let sum+=10
        ;;
3|5)
     $COLOR1'菜價(jià):$20'$END
     let sum+=20
     ;;
2)
     $COLOR1'菜價(jià):$888'$END
     let sum+=888
     ;;
6)
    $COLOR2"你點(diǎn)的菜品總價(jià)是:$sum"$END
     break
     ;;
*)
     echo "輸入錯(cuò)誤!"

     ;;
        esac
        $COLOR2"你點(diǎn)的菜品總價(jià)是:$sum"$END
done

4.2.6 循環(huán)控制 shift 命令

shift[n]用于將參量列表list 左移指定次數(shù),缺省為左移一次。

參量列表list 一旦被移動(dòng),最左端的那個(gè)參數(shù)就從列表中刪除。while 循環(huán)遍歷位置參量列表時(shí),常用到 shift

例:shift批量創(chuàng)建用戶

PASS=110420
while [ "$1" ];do
        useradd $1 && echo $1 is created || echo $1 is exists
        echo $PASS | passwd --stdin $1
        shift	#shift 1 一次只跳過(guò)1個(gè),2則跳過(guò)2個(gè)
done
[root@CentOS8 scripts]#bash shift_user.sh Tom Alice
Tom is created
Changing password for user Tom.
passwd: all authentication tokens updated successfully.
Alice is created
Changing password for user Alice.
passwd: all authentication tokens updated successfully.

例:判斷某個(gè)ip訪問(wèn)的次數(shù)

[root@CentOS8 data]#sed -En '/^ESTAB/s#.*[: ]([^:]+):[0-9]+ $#\1#p' ss.log | sort |uniq -c
		1	10.0.0.1
	200	10.0.0.8

4.2.7 while read 特殊用法

while循環(huán)的特殊用法,遍歷文件或文本的每一行,即逐行處理

支持stdin

格式

while read line; do
	循環(huán)體
done < /PATH/FROM/SOMEFILE

說(shuō)明:依次讀取/PATH/FROM/SOMEFILE文件中的每一行,且將行賦值給變量line

例:

[root@centos8 ~]#echo joyce | read X ; echo $X	# 管道|開(kāi)啟子進(jìn)程

[rootcentos8 ~]#echo joyce | while read X ; do echo $X;done
joyce

[root@centos8 ~]#echo joyce | { read X ; echo $X; }
joyce

[root@centos8 ~]#echo joyce | ( read X ; echo $X )
joyce

[root@centos8 ~]#echo joyce wang zhang | ( read X Y Z; echo $X $Y $Z )
joyce wang zhang

  [root@centos8 ~]#echo joyce wang zhang | while read X Y Z; do echo $X $Y $Z;done
joyce wang zhang

例:使用while read實(shí)現(xiàn)磁盤(pán)報(bào)警

WARNING=10
MAIL=1299575088@qq.com
df |sed -nr "/^\/dev\/sd/s#^([^ ]+) .* ([0-9]+)%.*#\1 \2#p" |while read DEVICE USE;do
        if [ $USE -gt $WARNING ] ;then
                echo "$DEVICE will be full,use:$USE" |  mail -s "DISK WARNING" $MAIL
        fi
done

例:查看/sbin/nologin的shell類型的用戶名和UID

while read line ;do
                if [[ "$line" =~ /sbin/nologin$  ]] ; then
                        echo $line | cut -d: -f1,3
                fi
done < /etc/passwd

例:存放大量單詞文件

[root@CentOS8 scripts]#wc -l /usr/share/dict/linux.words
479828 /usr/share/dict/linux.words

4.2.8 select 循環(huán)與菜單

格式:

select NAME [in WORDS ... ;] do COMMANDS; done

select variable in list ;do
	循環(huán)體命令
done

說(shuō)明

  • select 循環(huán)主要用于創(chuàng)建菜單,按數(shù)字順序排列的菜單項(xiàng)顯示在標(biāo)準(zhǔn)錯(cuò)誤上,并顯示 PS3 提示符,等待用戶輸入
  • 用戶輸入菜單列表中的某個(gè)數(shù)字,執(zhí)行相應(yīng)的命令
  • 用戶輸入被保存在內(nèi)置變量REPLY中
  • select 是個(gè)無(wú)限循環(huán),因此要記住用 break 命令退出循環(huán),或用exit 命令終止腳本。也可以按 ctrl+c 退出循
  • select經(jīng)常和 case 聯(lián)合使用
  • 與for 循環(huán)類似,可以省略 in list,此時(shí)使用位置參量

5 函數(shù)介紹

5.1 管理函數(shù)

函數(shù)由兩部分組成:函數(shù)名和函數(shù)體

幫助參看:help function

5.1.1 定義函數(shù)

function name { COMMANDS ; } or name () { COMMANDS ; }
 
#語(yǔ)法一:
func_name () {
	...函數(shù)體...
}

#語(yǔ)法二:
function func_name {
	...函數(shù)體...
}

#語(yǔ)法三:
function func_name () {
	...函數(shù)體...
}

例:創(chuàng)建disable_firewall_selinux函數(shù)以關(guān)閉firewalld和selinux

[root@centos8_3 ~]#systemctl status firewalld
● firewalld.service - firewalld - dynamic firewall daemon
   Loaded: loaded (/usr/lib/systemd/system/firewalld.service; enabled; vendor preset: enabled)
   Active: active (running) since Sat 2023-08-12 22:57:44 CST; 6min ago
[root@centos8_3 ~]#getenforce
Enforcing

# 函數(shù)主體:
[root@centos8_3 ~]#disable_firewall_selinux () {
> systemctl stop firewalld
> systemctl disable firewalld
> sed -i 's/SELINUX=enforcing/SELINUX=disabled/' /etc/selinux/config
> setenforce 0
> }

[root@centos8_3 ~]#disable_firewall_selinux
Removed /etc/systemd/system/multi-user.target.wants/firewalld.service.
Removed /etc/systemd/system/dbus-org.fedoraproject.FirewallD1.service.
[root@centos8_3 ~]#systemctl status firewalld
● firewalld.service - firewalld - dynamic firewall daemon
   Loaded: loaded (/usr/lib/systemd/system/firewalld.service; disabled; vendor preset: enabled)
   Active: inactive (dead)
[root@centos8_3 ~]#getenforce
Permissive

注意:函數(shù)操作后確實(shí)修改了文件,因此重啟后仍然保存。但是函數(shù)本身一次性使用,重啟后消失,因此想要保存函數(shù)需要寫(xiě)入到文件

例:分裝函數(shù)與調(diào)用于2個(gè)文件,可直接調(diào)用函數(shù)

#funtions文件,保存函數(shù)主體
[root@centos8_3 scripts]#cat functions
#函數(shù)1:disable_firewall_selinux()
disable_firewall_selinux () {
 systemctl stop firewalld
 systemctl disable firewalld
 sed -i 's/SELINUX=enforcing/SELINUX=disabled/' /etc/selinux/config
 setenforce 0
}

#函數(shù)2:yum_repo()
yum_repo() {

        cd /etc/yum.repos.d/
        mkdir backup
        mv *.repo backup
        cat > base.repo <<EOF

[BaseOS]
name=aliyun BaseOS
baseurl = https://mirrors.aliyun.com/centos/8/BaseOS/x86_64/os/
                  https://repo.huaweicloud.com/centos/8-stream/BaseOS/x86_64/os/
gpgcheck=1
enabled=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-centosofficial

[AppStream]
name=aliyun AppStream
baseurl = https://mirrors.aliyun.com/centos/8/AppStream/x86_64/os/
                  https://repo.huaweicloud.com/centos/8-stream/AppStream/x86_64/os/
gpgcheck=1
enabled=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-centosofficial

[epel]
name=Extra Packages for Enterprise Linux \$releasever - \$basearch
# It is much more secure to use the metalink, but if you wish to use a local mirror
# place it's address here.
#baseurl=https://download.example/pub/epel/\$releasever/Everything/\$basearch
metalink=https://mirrors.fedoraproject.org/metalink?repo=epel-\$releasever&arch=\$basearch&infra=\$infra&content=\$contentdir
enabled=1
gpgcheck=1
countme=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-8

[epel-debuginfo]
name=Extra Packages for Enterprise Linux \$releasever - \$basearch - Debug
# It is much more secure to use the metalink, but if you wish to use a local mirror
# place it's address here.
#baseurl=https://download.example/pub/epel/\$releasever/Everything/\$basearch/debug
metalink=https://mirrors.fedoraproject.org/metalink?repo=epel-debug-\$releasever&arch=\$basearch&infra=\$infra&content=\$contentdir
enabled=0
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-8
gpgcheck=1

[epel-source]
name=Extra Packages for Enterprise Linux \$releasever - \$basearch - Source
# It is much more secure to use the metalink, but if you wish to use a local mirror
# place it's address here.
#baseurl=https://download.example/pub/epel/\$releasever/Everything/SRPMS
metalink=https://mirrors.fedoraproject.org/metalink?repo=epel-source-\$releasever&arch=\$basearch&infra=\$infra&content=\$contentdir
enabled=0
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-8
gpgcheck=1
EOF
}

#函數(shù)3:install_package()
install_package() {
packages="
vim
tree
autofs
net-tools
apache
httpd
"
for i in $packages;do
        rpm -q $i &> /dev/null || yum -q -y install $i
done
}

#disable_firewall_selinux.sh文件,調(diào)用disable_firewall_selinux函數(shù)
[root@centos8_3 scripts]#cat disable_firewall_selinux.sh
#!/bin/bash
. functions	#引用functions文件

disable_firewall_selinux

#yum_repo.sh文件,調(diào)用yum_repo函數(shù)
[root@centos8_3 scripts]#cat yum_repo.sh
#!/bin/bash
. functions

yum_repo

#install_package.sh文件,調(diào)用install_package函數(shù)
[root@centos8_3 scripts]#cat install_package.sh
#!/bin/bash
. functions

install_package

5.1.2 查看函數(shù)

#查看當(dāng)前已定義的函數(shù)名
declare -F

#查看當(dāng)前已定義的函數(shù)定義
declare -f

5.1.3 刪除函數(shù)

格式:

unset func_name

5.2 函數(shù)調(diào)用

函數(shù)的調(diào)用方式

  • 可在交互式環(huán)境下定義函數(shù)
  • 可將函數(shù)放在腳本文件中作為它的一部分
  • 可放在只包含函數(shù)的單獨(dú)文件中

調(diào)用:函數(shù)只有被調(diào)用才會(huì)執(zhí)行,通過(guò)給定函數(shù)名調(diào)用函數(shù),函數(shù)名出現(xiàn)的地方,會(huì)被自動(dòng)替換為函數(shù)代碼

函數(shù)的生命周期:被調(diào)用時(shí)創(chuàng)建,返回時(shí)終止。

不過(guò)調(diào)用函數(shù)時(shí),如果函數(shù)內(nèi)外有同名變量,調(diào)用函數(shù)后會(huì)修改函數(shù)內(nèi)外的變量,類似于全局變量,如果要使函數(shù)只修改函數(shù)內(nèi)部的變量而不影響函數(shù)外的同名變量,可以在函數(shù)內(nèi)聲明時(shí)加上local,使其成為本地變量,如local NAME=1

5.2.1 交互式環(huán)境調(diào)用函數(shù)

交互式環(huán)境下定義和使用函數(shù)

5.2.2 在腳本中定義及使用函數(shù)

函數(shù)在使用前必須定義,因此應(yīng)將函數(shù)定義放在腳本開(kāi)始部分,直至shell首次發(fā)現(xiàn)它后才能使用,調(diào)用函數(shù)僅使用其函數(shù)名即可

5.2.3 使用函數(shù)文件

例:調(diào)用系統(tǒng)函數(shù)

[root@CentOS8 ~]#. /etc/init.d/functions
[root@CentOS8 ~]#action "you an me"
you an me                                                  [  OK  ]
[root@CentOS8 ~]#action "you an medsadsad" false
you an medsadsad                                           [FAILED]

5.3 函數(shù)返回值

默認(rèn)情況下,我們使用exit 100,會(huì)返回100,但用在函數(shù)里,會(huì)使整個(gè)腳本退出而不執(zhí)行下面的代碼。

因此使用return #返回值,可只退出當(dāng)前函數(shù)而不退出腳本,不過(guò)只在函數(shù)中使用

函數(shù)的執(zhí)行結(jié)果返回值

  • 使用echo等命令進(jìn)行輸出
  • 函數(shù)體中調(diào)用命令的輸出結(jié)果

函數(shù)的退出狀態(tài)碼

  • 默認(rèn)取決于函數(shù)中執(zhí)行的最后一條命令的退出狀態(tài)碼

  • 自定義退出狀態(tài)碼,其格式為

    • return 從函數(shù)中返回,用最后狀態(tài)命令決定返回值

    • return 0 無(wú)錯(cuò)誤返回

    • return 1-255 有錯(cuò)誤返回

5.4 環(huán)境函數(shù)

類擬于環(huán)境變量,也可以定義環(huán)境函數(shù),使子進(jìn)程也可使用父進(jìn)程定義的函數(shù)

定義環(huán)境函數(shù):

export -f function_name
declare -xf function_name

查看環(huán)境函數(shù):

export -f
declare -xf

5.5 函數(shù)參數(shù)

函數(shù)可以接受參數(shù):

  • 傳遞參數(shù)給函數(shù),在函數(shù)名后面以空白分隔給定參數(shù)列表即可,如: testfunc arg1 arg2…
  • 在函數(shù)體中當(dāng)中,可使用$1, 2 , . . . 調(diào)用這些參數(shù),還可以使用 2,...調(diào)用這些參數(shù),還可以使用 2...調(diào)用這些參數(shù),還可以使用@, ? , *, ?,#等特殊變量

5.6 函數(shù)變量

變量作用域:

  • 普通變量:只在當(dāng)前shell進(jìn)程有效,為執(zhí)行腳本會(huì)啟動(dòng)專用子shell進(jìn)程;因此,本地變量的作用范圍是當(dāng)前shell腳本程序文件,包括腳本中的函數(shù)
  • 環(huán)境變量:當(dāng)前shell和子shell有效
  • 本地變量:函數(shù)的生命周期;函數(shù)結(jié)束時(shí)變量被自動(dòng)銷毀

注意:

  • 如果函數(shù)中定義了普通變量,且名稱和局部變量相同,則使用本地變量
  • 由于普通變量和局部變量會(huì)沖突,建議在函數(shù)中只使用本地變量

在函數(shù)中定義本地變量的方法

local NAME=VALUE

5.7 函數(shù)遞歸

函數(shù)遞歸:函數(shù)直接或間接調(diào)用自身,注意遞歸層數(shù),可能會(huì)陷入死循環(huán)

  • 基例:確定值
  • 鏈條:規(guī)律

遞歸示例:階乘

階乘是基斯頓·卡曼于1808 年發(fā)明的運(yùn)算符號(hào),是數(shù)學(xué)術(shù)語(yǔ),一個(gè)正整數(shù)的階乘(factorial)是所有小于及等于該數(shù)的正整數(shù)的積,并且有0的階乘為1,自然數(shù)n的階乘寫(xiě)作n!

n!=1x2x3x…xn

階乘亦可以遞歸方式定義: 0!=1,n!=(n-1)!xn

n!=n(n-1)(n-2)…1

n(n-1)!=n(n-1)(n-2)!

例:遞歸實(shí)現(xiàn)階乘

[root@CentOS8 functions]#cat fact.sh
fact() {
        if [ $1 -eq 1  ];then
                echo 1
        else
                echo $[`fact $[$1-1]`*$1]
        fi
}
fact $1

[root@CentOS8 functions]#bash fact.sh 5
120

fork炸彈是一種惡意程序,它的內(nèi)部是一個(gè)不斷在 fork 進(jìn)程的無(wú)限循環(huán),實(shí)質(zhì)是一個(gè)簡(jiǎn)單的遞歸程序。由于程序是遞歸的,如果沒(méi)有任何限制,這會(huì)導(dǎo)致這個(gè)簡(jiǎn)單的程序迅速耗盡系統(tǒng)里面的所有資源

參考:https://en.wikipedia.org/wiki/Fork_bomb

函數(shù)實(shí)現(xiàn)

:(){ :|:& };:	#無(wú)基例
bomb () {} bomb | bomb & }; bomb

腳本實(shí)現(xiàn)

cat Bomb.sh
#!/bin/bash
./$0|./$0&

Linux_5_Shell腳本編程,Linux,linux,運(yùn)維

OOM:內(nèi)存溢出

6 其它腳本相關(guān)工具

6.1 信號(hào)捕捉 trap

  • trap ‘觸發(fā)指令’ 信號(hào)

    ? 進(jìn)程收到系統(tǒng)發(fā)出的指定信號(hào)后,將執(zhí)行自定義指令,而不會(huì)執(zhí)行原操作

  • trap" 信號(hào)

    ? 忽略信號(hào)的操作

  • trap ‘-’ 信號(hào)

    ? 恢復(fù)原信號(hào)的操作

  • trap -p

    ? 列出自定義信號(hào)操作

  • trap finish EXIT

    ? 當(dāng)腳本退出時(shí),執(zhí)行finish函數(shù)

例:

[root@CentOS8 functions]#cat signal_trap1.sh
trap 'echo "Press ctrl+c"' int quit	#將int 和quit信號(hào)改為echo "Press ctrl+c"
trap -p
for((i=1;i<=10;i++))
do
        sleep 1
        echo $i
done

trap '' int		#將int信號(hào)改為空,即忽略
trap -p
for((i=11;i<21;i++ ))
do
        sleep 1
        echo $i
done

trap '-' int	#恢復(fù)int信號(hào),接下來(lái)遇到int信號(hào)將執(zhí)行ctrl+c
trap -p
for(( i=21;i<31;i++))
do
        sleep 1
        echo $i
done

[root@CentOS8 functions]#bash signal_trap1.sh
trap -- 'echo "Press ctrl+c"' SIGINT
trap -- 'echo "Press ctrl+c"' SIGQUIT
1
^CPress ctrl+c
2
^CPress ctrl+c
3
^CPress ctrl+c
4
^CPress ctrl+c
5
^CPress ctrl+c
6
^CPress ctrl+c
7
^CPress ctrl+c
8
^CPress ctrl+c
9
^CPress ctrl+c
10
trap -- '' SIGINT
trap -- 'echo "Press ctrl+c"' SIGQUIT
^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^[[A11
^[[A12
^[[A^[[A^[[A^C13
^C^C^C^C^C^C^C^C^C^C^C14
15
16
17
18
19
20
trap -- 'echo "Press ctrl+c"' SIGQUIT
21
22
23
24
25
26
^C

6.2 創(chuàng)建臨時(shí)文件 mktemp

mktemp命令用于創(chuàng)建并顯示臨時(shí)文件,可避免沖突

格式

mktemp [OPTION]... [TEMPLATE]

說(shuō)明:TEMPLATE:filenameXXX,X至少要出現(xiàn)三個(gè)

常見(jiàn)選項(xiàng):

-d	創(chuàng)建臨時(shí)目錄
-p 	DIR或--tmpdir=DIR	指明臨時(shí)文件所存放目錄位置

例:

#默認(rèn)放在tmp目錄下
[root@CentOS8 functions]#mktemp
/tmp/tmp.B9CHlgxwCL
[root@CentOS8 functions]#mktemp
/tmp/tmp.ur2MYKCZhU

[root@CentOS8 ~]#mktemp -d tmpdirXXXX	#在當(dāng)前目錄下生成臨時(shí)目錄
tmpdirqWDe
[root@CentOS8 ~]#ll tmpdirqWDe -d
drwx------ 2 root root 6 Aug 13 14:51 tmpdirqWDe

例:實(shí)現(xiàn)rm的進(jìn)階寫(xiě)法

[root@CentOS8 scripts]#cat rm2.sh
DIR=`mktemp -d /tmp/trash-$(date +%F_%H-%M-%S)XXXXX`
mv $* $DIR
echo $* is move to $DIR

[root@CentOS8 scripts]#bash  rm2.sh 123 321
123 321 is move to /tmp/trash-2023-08-13_14-59-58BDIIO
[root@CentOS8 scripts]#ls /tmp/trash-2023-08-13_14-59-58BDIIO/
123  321
[root@CentOS8 scripts]#alias rm=/data/scripts/rm2.sh
[root@CentOS8 scripts]#touch 1
[root@CentOS8 scripts]#chmod +x rm2.sh
[root@CentOS8 scripts]#rm 1
1 is move to /tmp/trash-2023-08-13_15-05-24kBeQl

6.3 安裝復(fù)制文件 install

功能相當(dāng)于cp、chmod、chown、chgrp等相關(guān)工具的集合

install命令格式

install [OPTION]... [-T] SOURCE DEST 單文件
install [OPTION]... SOURCE... DIRECTORY
install [OPTION]... -t DIRECTORY SOURCE...
insta11 [OPTION]... -d DIRECTORY...創(chuàng)建空目錄

選項(xiàng):

-m MODE,默認(rèn)755	#改權(quán)限
-o OWNER				#改所有者
-g GROUP				#改所屬組
-d DIRNAME

例:

[root@CentOS8 ~]#ll cal.txt
-rw-r--r-- 1 root root 0 Jul 28 19:29 cal.txt
[root@CentOS8 ~]#install -m 666 -o joyce -g bin cal.txt /data/test.txt
[root@CentOS8 ~]#ll /data/test.txt
-rw-rw-rw- 1 joyce bin 0 Aug 13 15:12 /data/test.txt

#創(chuàng)建空文件夾
[root@CentOS8 ~]#install -m 700 -o joyce -g daemon -d /data/testdir/
[root@CentOS8 ~]#ll -d /data/testdir/
drwx------ 2 joyce daemon 6 Aug 13 15:13 /data/testdir/

6.4 交互式轉(zhuǎn)化批處理工具 expect

expect 是由 Don Libes 基于 TcI ( Tool Command Language )語(yǔ)言開(kāi)發(fā)的,主要應(yīng)用于自動(dòng)化交互式操作的場(chǎng)景,借助 expect處理交互的命令,可以將交互過(guò)程如:ssh登錄,tp登錄等寫(xiě)在一個(gè)腳本上,使之自動(dòng)化完成尤其適用于需要對(duì)多臺(tái)服務(wù)器執(zhí)行相同操作的環(huán)境中,可以大大提高系統(tǒng)管理人員的工作效率

expect 語(yǔ)法:

expect [選項(xiàng)] [ -c cmds ] [ [ -[fIb] ] cmdfile ] [ args ]

常見(jiàn)選項(xiàng):

-c	從命令行執(zhí)行expect腳本,默認(rèn)expect是交互地執(zhí)行的
-d	可以輸出輸出調(diào)試信息

示例:

expect -c 'expect "\n" {send "pressed enter\n"}'
expect -d ssh.exp

expect中相關(guān)命令

spawn		啟動(dòng)新的進(jìn)程
expect	從進(jìn)程接收字符串
send		用于向進(jìn)程發(fā)送字符串
interact	允許用戶交互
exp_continue 匹配多個(gè)字符串在執(zhí)行動(dòng)作后加此命令

expect最常用的語(yǔ)法 ( tcl語(yǔ)言:模式-動(dòng)作 )

單一分支模式語(yǔ)法:只生效一次,遇到hi輸出后即結(jié)束

[root@centos8 test]#expect
expect1.1> expect "hi" {send "You said hi\n"}
hahahixixi
You said hi

例:非交互式發(fā)送文件至第二個(gè)主機(jī),自動(dòng)輸入yes和密碼

#!/usr/bin/expect	#注意,不是bash
spawn scp /etc/fstab 10.0.0.7:/data
expect {
			"yes/no" { send "yes\n",exp_continue }
			"password" { send "110420\n" }
}
expect eof

例:非交互式自動(dòng)登錄至第二個(gè)ip主機(jī),自動(dòng)輸入yes和密碼

[root@centos8 scripts]#cat expect2
#!/usr/bin/expect
spawn ssh 10.0.0.209
expect {
			"yes/no" { send "yes\n";exp_continue }
			"password" { send "110420\n" }
}	
interact
[root@CentOS8 scripts]#chmod +x expect1.sh
[root@CentOS8 scripts]#./expect1.sh
spawn ssh 10.0.0.209
root@10.0.0.209's password:
hello Joyce!
Nna
Activate the web console with: systemctl enable --now cockpit.socket

Last login: Sun Aug 13 15:48:51 2023 from 10.0.0.201
[root@centos8_2 ~]#hostname
centos8_2

例:帶有參數(shù)的自動(dòng)登錄其他ip主機(jī)的腳本,自動(dòng)輸入yes和密碼

[root@CentOS8 scripts]#cat ./expect2.sh
#!/usr/bin/expect
set ip 10.0.0.209
set user root
set password 110420
set timeout 10
spawn ssh $user@$ip
expect {
                "yes/no" { send "yes\n";exp_continue }
                "password" {  send "$password\n" }
}
interact	#代表可以進(jìn)行交互

[root@CentOS8 scripts]#chmod +x expect2.sh
[root@CentOS8 scripts]#./expect2.sh
spawn ssh root@10.0.0.209
root@10.0.0.209's password:
hello Joyce!
Nna
Activate the web console with: systemctl enable --now cockpit.socket

Last login: Sun Aug 13 15:49:06 2023 from 10.0.0.201

例:使用位置參數(shù)實(shí)現(xiàn)自動(dòng)登錄其他ip的主機(jī)

[root@CentOS8 scripts]#cat ./expect3.sh
#!/usr/bin/expect
set ip [lindex $argv 0]
set user [lindex $argv 1]
set password [lindex $argv 2]
spawn ssh $user@$ip
expect {
			"yes/no" { send "yes\n";exp_continue }
			"password" { send "$password\n" }
}
interact
[root@CentOS8 scripts]#chmod +x expect3.sh
[root@centos8 scripts]#./expect3 10.0.0.209 root 110420
spawn ssh roota10.0.0.7
roota10.0.0.209's password:
Last login: wed Apr 29 15:34:14 2020 from 10.0.0.8

例:遠(yuǎn)程登陸主機(jī)并創(chuàng)建賬號(hào)設(shè)置密碼,完了退出

#!usr/bin/expect
set	ip [lindex $argv 0]
set	user [lindex $argv 1]
set	password [lindex $argv 2]
set timeout 10
spawn ssh $user@$ip
expect {
			"yes/no" { send "yes\n";exp_continue }
			"password"{ send"$password\n" }
}
#  ]#即登陸后輸入內(nèi)容前面的標(biāo)識(shí)符
expect "]#" { send "useradd haha\n" }
expect "]#" { send "echo 110420 |passwd --stdin haha\n" }
send "exit\n"
expect eof

例:在bash腳本里調(diào)用expect以遠(yuǎn)程登錄主機(jī)并創(chuàng)建賬號(hào)設(shè)置密碼

[root@CentOS8 scripts]#cat ./expect5.sh
#!/bin/bash
ip=$1
user=$2
password=$3
expect <<EOF
set timeout 10
spawn ssh $user@$ip
expect {
			"yes/no" { send "yes\n";exp_continue }
			"password"{ send"$password\n" }
}
#  ]#即登陸后輸入內(nèi)容前面的標(biāo)識(shí)符
expect "]#" { send "useradd haha\n" }
expect "]#" { send "echo 110420 |passwd --stdin haha\n" }
send "exit\n"
expect eof
EOF

[root@CentOS8 scripts]#bash expect5.sh 10.0.0.209 root 110420

例:批量登錄不同主機(jī)并創(chuàng)建用戶設(shè)置密碼

#!/bin/bash
NET=10.0.0
user=root
password=110420
for ID in 209 210;do	#循環(huán)遍歷不同IP的主機(jī)
ip=$NET.$ID
expect <<EOF
set timeout 20
spawn ssh $user@$ip
expect {
			"yes/no" { send "yes\n";exp_continue }
			"password" { send "$password\n" }
}
expect "#" { send "useradd test\n" }
expect "#" { send "exit\n" }
expect eof
EOF
done

例:批量登錄不同主機(jī)并修改selinux為disabled

#!/bin/bash
NET=10.0.0
user=root
password=110420
for ID in 209 210;do	#循環(huán)遍歷不同IP的主機(jī)
ip=$NET.$ID
expect <<EOF
set timeout 20
spawn ssh $user@$ip
expect {
			"yes/no" { send "yes\n";exp_continue }
			"password" { send "$password\n" }
}
expect "#" { send "sed -i 's/^SELINUX=enforcing/SELINUX=disabled/' /etc/selinux/confiig\n" }
expect "#" { send "setenforce 0\n" }
expect "#" { send "exit\n" }
expect eof
EOF
done

7數(shù)組

7.1 數(shù)組介紹

變量:存儲(chǔ)單個(gè)元素的內(nèi)存空間

數(shù)組:存儲(chǔ)多個(gè)元素的連續(xù)的內(nèi)存空間,相當(dāng)于多個(gè)變量的集合

數(shù)組名和索引

  • 索引的編號(hào)從0開(kāi)始,屬于數(shù)值索引
  • 索引可支持使用自定義的格式,而不僅是數(shù)值格式,即為關(guān)聯(lián)索引,bash4.0版本之后開(kāi)始支持
  • bash的數(shù)組支持稀疏格式(索引不連續(xù))

7.2 聲明數(shù)組

#普通數(shù)組可以不事先聲明,直接使用
declare -a ARRAY_NAME

#關(guān)聯(lián)數(shù)組必須先聲明,再使用
declare -A ARRAY_NAME

注意:兩者不可相互轉(zhuǎn)換

7.3 數(shù)組賦值

數(shù)組元素的賦值

  1. 一次只賦值一個(gè)元素

    ARRAY_NAME[INDEX]=VALUE
    

    例:

    [root@CentOS8 ~]#title[0]=ceo
    [root@CentOS8 ~]#echo ${title}
    ceo
    
  2. 一次賦值全部元素

    ARRAY_NAME=("VAL1" "VAL2" "VAL3"...)
    

    例:

    title=("ceo""coo""cto")
    num=({0..10})
    alpha=({a..g})
    file=( *.sh )
    
  3. 只賦值特定元素

    ARRAY_NAME=([0]="VAL1" [3]="VAL2" ...)
    
  4. 交互式數(shù)組值對(duì)賦值

    read -a ARRAY
    
    [root@CentOS8 ~]#read -a number
    1 3 5 7 9
    [root@CentOS8 ~]#echo ${number[*]}
    1 3 5 7 9
    [root@CentOS8 ~]#echo ${number[2]}
    5
    [root@CentOS8 ~]#echo ${number}
    1
    

7.4 顯示所有數(shù)組

顯示所有數(shù)組

declare -a

7.5 引用數(shù)組

引用數(shù)組元素

${ARRAY_NAME[INDEX]}
#如果省略[INDEX]表示引用下標(biāo)為0的元素

引用數(shù)組所有元素

${ARRAY_NAME[*]}
${ARRAY_NAME[@]}

例:

[root@CentOS8 ~]#NUM=({1..5})
[root@CentOS8 ~]#echo ${NUM[3]}
4
[root@CentOS8 ~]#echo ${NUM[2]}
3
[root@CentOS8 ~]#echo ${NUM[*]}
1 2 3 4 5
[root@CentOS8 ~]#echo ${NUM[@]}
1 2 3 4 5

例:

[root@CentOS8 ~]#read -a number
1 3 5 7 9
[root@CentOS8 ~]#echo ${number[*]}
1 3 5 7 9
[root@CentOS8 ~]#echo ${number[2]}
5
[root@CentOS8 ~]#echo ${number}
1

7.6 刪除數(shù)組

刪除數(shù)組中的某元素,會(huì)導(dǎo)致稀疏格式

unset ARRAY[INDEX]

例:

[root@centos8 ~]#echo $title[*]}
ceo coo cto
[root@centos8 ~]#unset title[1]
[root@centos8 ~]#echo $ftitle[*]]
ceo cto

刪除整個(gè)數(shù)組

unset ARRAY

例:

[root@centos8 ~]#unset title
[root@centos8 ~]#echo ${title[*]}

7.7 數(shù)組數(shù)據(jù)處理

數(shù)組切片

${ARRAY[@]:offset:number}
offset	#要跳過(guò)的元素個(gè)數(shù)
number	#要取出的元素個(gè)數(shù)

{ARRAY[@]:offset}	#取偏移量之后的所有元素

例:

[root@centos8 ~]#num=({0..10})
[root@centos8 ~]#echo ${num[*]:2:3}
2 3 4
[root@centos8 ~]#echo ${num[*]:6}
6 7 8 9 10

向數(shù)組中追加元素:

ARRAY[${#ARRAY[*]}]=value
ARRAY[${#ARRAY[@]}]=value

例:

[root@CentOS8 ~]#num=({0..10})
[root@CentOS8 ~]#echo ${num[2]}
2
[root@CentOS8 ~]#echo ${num[*]}
0 1 2 3 4 5 6 7 8 9 10
[root@CentOS8 ~]#num[11]=11
[root@CentOS8 ~]#echo ${num[*]}
0 1 2 3 4 5 6 7 8 9 10 11
[root@CentOS8 ~]#echo ${#num[*]}
12
[root@CentOS8 ~]#num[${#num[*]}]=12
[root@CentOS8 ~]#echo ${#num[*]}
13
[root@CentOS8 ~]#echo ${num[*]}
0 1 2 3 4 5 6 7 8 9 10 11 12

7.8 關(guān)聯(lián)數(shù)組

declare -A ARRAY_NAME
ARRAY_NAME=([idx_namel]='val1' [idx_name2]='val2'...

注意:關(guān)聯(lián)數(shù)組必須先聲明再調(diào)用

例:

[root@CentOS8 ~]#declare -A name
[root@CentOS8 ~]#name[first]=Tom
[root@CentOS8 ~]#name[second]=Jack
[root@CentOS8 ~]#name[third]=Case
[root@CentOS8 ~]#echo ${name[first]}
Tom
[root@CentOS8 ~]#echo ${name[*]}
Case Jack Tom
[root@CentOS8 ~]#echo ${name[third]}
Case

7.9 范例

例:生成包含10個(gè)隨機(jī)數(shù)的數(shù)組,并顯示其中的最大值MAX和最小值MIN

[root@CentOS8 test]#cat random1.sh
#!/bin/bash
declare -i min max
declare -a nums
for ((i=0;i<10;i++));do
        nums[$i]=$RANDOM
        [ $i -eq 0 ] && min=${nums[0]} && max=${nums[0]}&& continue
        [ ${nums[$i]} -gt $max ] && max=${nums[$i]}
        [ ${nums[$i]} -lt $min ] && min=${nums[$i]}
done
echo "All numbers are ${nums[*]}"
echo Max is $max
echo min is $min

[root@CentOS8 test]#bash random1.sh
All numbers are 23203 6083 14719 18022 31925 25880 9039 10908 30266 23092
Max is 31925
min is 6083

8 字符串處理

8.1 字符串切片

基于偏移量取字符串

#返回字符串變量var的長(zhǎng)度
${#var}

#返回字符串變量var中從第offset個(gè)字符后(不包括第offset個(gè)字符)的字符開(kāi)始,到最后的部分,offset的取值在0到${#var}-1 之間(bash4.2后,允許為負(fù)值)
${var:offset]

#返回字符串變量var中從第offset個(gè)字符后(不包括第offset個(gè)字符)的字符開(kāi)始,長(zhǎng)度為number的部分
${var:offset:number}

#取字符串的最右側(cè)幾個(gè)字符,取字符串的最右側(cè)幾個(gè)字符,注意: 冒號(hào)后必須有一空白字符
${var: -length}

#從最左側(cè)跳過(guò)offset字符,一直向右取到距離最右側(cè)lengh個(gè)字符之前的內(nèi)容,即:掐頭去尾
${var:offset:-length}

#先從最右側(cè)向左取到length個(gè)字符開(kāi)始,再向右取到距離最右側(cè)offset個(gè)字符之間的內(nèi)容,注意: -length前空格
${var: -length:-offset}

例:

[root@CentOS8 test]#str=123abc哇哦
[root@CentOS8 test]#echo ${#str}
8
[root@CentOS8 test]#echo ${str:5}
c哇哦
[root@CentOS8 test]#echo ${str:5:2}
c哇
[root@CentOS8 test]#echo ${str: -2}
哇哦
[root@CentOS8 test]#echo ${str:3:-2}
abc
[root@CentOS8 test]#echo ${str: -3:-1}	#取倒數(shù)3個(gè)和倒數(shù)1個(gè)之間的2個(gè)
c哇

基于模式取子串

從左往右:

#其中word可以是指定的任意字符,自左而右,查找var變量所存儲(chǔ)的字符串中,第一次出現(xiàn)的word,刪除字符串開(kāi)頭至第一次出現(xiàn)word字符串 (含) 之間的所有字符
${var#*word}:

#同上,貪婪模式,不同的是,刪除的是字符串開(kāi)頭至最后一次由word指定的字符之間的所有內(nèi)容
${var##*word}:

例:

[root@centos8 ~]#file="var/log/messages"
[root@centos8 ~]#echo ${file#*/}
log/messages
[root@centos8 ~]#echo ${file##*/}
messages

從右往左:

#其中word可以是指定的任意字符,功能,自右而左,查找var變量所存儲(chǔ)的字符串中,第一次出現(xiàn)的worc,刪除字符串最后一個(gè)字符向左至第一次出現(xiàn)word字符串 (含) 之間的所有字符
${var%word*}

#同上,只不過(guò)刪除字符串最右側(cè)的字符向左至最后一次出現(xiàn)word字符之間的所有字符
${var%%word*}

例:

[root@centos8 ~]#file="/var/log/messages"
[root@centos8 ~]#echo ${file%/*}
var/log
[root@centos8 ~]#echo ${file%%/*}
var

8.2 查找替換、

#查找var所表示的字符串中,第一次被pattern所匹配到的字符串,以substr替換之
${var/pattern/substr}

#查找var所表示的字符串中,所有能被pattern所匹配到的字符串,以substr替換之
${var//pattern/substr}

#查找var所表示的字符串中,行首被pattern所匹配到的字符串,以substr替換之
${var/#pattern/substr}

#查找var所表示的字符串中,行尾被pattern所匹配到的字符串,以substr替換之
${var/%pattern/substr}

8.3 查找并刪除

#刪除var表示的字符串中第一次被pattern匹配到的字符串
${var/pattern}

#刪除var表示的字符串中所有被pattern匹配到的字符串
${var//pattern}

#刪除var表示的字符串中所有以pattern為行首匹配到的字符串
${var/#pattern}

#刪除var所表示的字符串中所有以pattern為行尾所匹配到的字符串
${var/%pattern}

8.4 字符大小寫(xiě)轉(zhuǎn)換

#把var中的所有小寫(xiě)字母轉(zhuǎn)換為大寫(xiě)
${var^^}

#把var中的所有大寫(xiě)字母轉(zhuǎn)換為小寫(xiě)
${var,,}

例:

[root@CentOS8 test]#echo $str
123abc哇哦
[root@CentOS8 test]#echo ${str^^}
123ABC哇哦

9 高級(jí)變量

9.1 高級(jí)變量賦值

變量配置方法 str 沒(méi)有配置 str 為空字符串 str 已配置非為空字符串
var=${str-expr} var=expr var= var=$str
var=${str:-expr} var=expr var=expr var=$str
var=${str+expr} var= var=expr var=expr
var=${str:+expr} var= var= var=expr
var=${str=expr} str=expr
var=expr
str 不變
var=
str 不變
var=$str
var=${str:=expr} str=expr
var=expr
str=expr
var=expr
str 不變
var=$str
var=${str?expr} expr輸出至stderr var= var=sstr
var=${str:?expr} expr輸出至stderr expr輸出至stderr var=sstr

例:

[root@centos8 ~]#title=ceo
[root@centos8 ~]#name=${title-oops}
[root@centos8 ~]#echo $name
ceo

[root@centos8 ~]#title=
[root@centos8 ~]#name=${title-oops}
[root@centos8 ~]#echo $name


[root@centos8 ~]#unset title
[rootacentos8 ~]#name=$ftitle-oops}
[root@centos8 ~]#echo $name
oops

9.2 高級(jí)變量用法-有類型變量

Shell變量一般是無(wú)類型的,但是bash Shell提供了declare和typeset兩個(gè)命令用于指定變量的類型,兩個(gè)命令是等價(jià)的

declare [選項(xiàng)] 變量名
選項(xiàng):
-r	聲明或顯示只讀變量
-i	將變量定義為整型數(shù)
-a	將變量定義為數(shù)組
-A	將變量定義為關(guān)聯(lián)數(shù)組
-f	顯示已定義的所有函數(shù)名及其內(nèi)容
-F	僅顯示已定義的所有函數(shù)名
-x	聲明或顯示環(huán)境變量和函數(shù),相當(dāng)于export
-l	聲明變量為小寫(xiě)字母 declare -l var=UPPER
-u	聲明變量為大寫(xiě)字母 declare -u var=lower

9.3 變量間接引用

9.3.1 eval命令

eval命令將會(huì)首先掃描命令行進(jìn)行所有的置換,然后再執(zhí)行該命令。該命令適用于那些一次掃描無(wú)法實(shí)現(xiàn)其功能的變量,該命令對(duì)變量進(jìn)行兩次掃描,因此后面必須跟命令

例1:

[root@CentOS8 test]#CMD=hostname
[root@CentOS8 test]#$CMD
CentOS8.Joyce.person1
[root@CentOS8 test]#echo $CMD
hostname
[root@CentOS8 test]#eval $CMD
CentOS8.Joyce.person1

例2:

[root@CentOS8 test]#n=10
[root@CentOS8 test]#for i in {1..$n};do echo $i;done
{1..10}
[root@CentOS8 test]#for i in `eval echo {1..$n}`;do echo $i;done
1
2
3
4
5
6
7
8
9
10

9.3.2 間接變量引用

如果第一個(gè)變量的值是第二個(gè)變量的名字,從第一個(gè)變量引用第二個(gè)變量的值就稱為間接變量引用

variable1的值是variable2,而variable2又是變量名,variable2的值為value,間接變量引用是指通過(guò)variable1獲

得變量值value的行為

variablel=variable2
variable2=value

bash Shell提供了兩種格式實(shí)現(xiàn)間接變量引用

eval tempvar= \$Svariable1
tempvar=${!variable1}

例:文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-646889.html

[root@CentOS8 test]#ceo=name
[root@CentOS8 test]#name=Me
[root@CentOS8 test]#echo $ceo
name
[root@CentOS8 test]#echo $$ceo
7487ceo
[root@CentOS8 test]#echo \$$ceo
$name
[root@CentOS8 test]#eval echo \$$ceo
Me
#或:
[root@CentOS8 test]#echo ${!ceo}
Me

9.3.3變量引用reference

[root@centos8 ~]#cat test.sh
#!/bin/bash
ceo=ME
title=ceo
declare -n ref=$title
[ -R ref ] && echo reference
echo $ref
ceo=Joyce
echo $ref

[root@centos8 ~]#bash test.sh
reference
ME
Joyce

到了這里,關(guān)于Linux_5_Shell腳本編程的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來(lái)自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 【Linux命令行與Shell腳本編程】第十六章 Shell函數(shù)

    【Linux命令行與Shell腳本編程】第十六章 Shell函數(shù)

    腳本函數(shù)基礎(chǔ) 函數(shù)返回值 在函數(shù)中使用變量 數(shù)組變量和函數(shù) 函數(shù)遞歸 創(chuàng)建庫(kù) 在命令行中使用函數(shù) 可以將shell腳本代碼放入函數(shù)中封裝起來(lái),這樣就能在腳本的任意位置多次使用. 函數(shù)是一個(gè)腳本代碼塊,可以并在腳本中的任何位置重用它。當(dāng)需要在腳本中使用該代碼塊時(shí)

    2024年02月14日
    瀏覽(40)
  • 3.7 Linux shell腳本編程(分支語(yǔ)句、循環(huán)語(yǔ)句)

    3.7 Linux shell腳本編程(分支語(yǔ)句、循環(huán)語(yǔ)句)

    目錄 分支語(yǔ)句(對(duì)標(biāo)C語(yǔ)言中的if) 多路分支語(yǔ)句(對(duì)標(biāo)C語(yǔ)言中的swich case) 分支語(yǔ)句(對(duì)標(biāo)C語(yǔ)言中的if) 語(yǔ)法結(jié)構(gòu): ? ? ? ? ?if ? ?表達(dá)式 ? ? ? ? ??? ??? ?then ?命令表 ? ? ? ? ?fi ? ? 如果表達(dá)式為真, 則執(zhí)行命令表中的命令; 否則退出if語(yǔ)句, 即執(zhí)行fi后面的語(yǔ)句。

    2024年02月02日
    瀏覽(24)
  • Linux shell編程學(xué)習(xí)筆記29:shell自帶的 腳本調(diào)試 選項(xiàng)

    Linux shell編程學(xué)習(xí)筆記29:shell自帶的 腳本調(diào)試 選項(xiàng)

    Linux shell腳本的調(diào)試方法比較多,上次我們探討和測(cè)試了shell內(nèi)建命令set所提供的一些調(diào)試選項(xiàng),其實(shí) shell 本身也提供了一些調(diào)試選項(xiàng)。我們以bash為例來(lái)看看。 purleEndurer @ csdn ~ $ bash --help GNU bash, version 4.2.46(2)-release-(x86_64-redhat-linux-gnu) Usage: ?bash [GNU long option] [option] ... ? ? ?

    2024年02月04日
    瀏覽(16)
  • 【Linux命令行與Shell腳本編程】第十四章,呈現(xiàn)數(shù)據(jù)

    【Linux命令行與Shell腳本編程】第十四章,呈現(xiàn)數(shù)據(jù)

    第十四章 呈現(xiàn)數(shù)據(jù) 1.1,標(biāo)準(zhǔn)文件描述符 文件描述符 縮寫(xiě) 描述 0 STDIN 標(biāo)準(zhǔn)輸入 1 STDOUT 標(biāo)準(zhǔn)輸出 2 STDERR 標(biāo)準(zhǔn)錯(cuò)誤 1.1.1,STDIN 標(biāo)準(zhǔn)輸入 1.1.2,STDOUT 標(biāo)準(zhǔn)輸出 1.1.3,STDERR 錯(cuò)誤輸出 1.2,重定向錯(cuò)誤 1.2.1.只重定向錯(cuò)誤 n 1.2.2.重定向錯(cuò)誤消息和正常輸出 2.1,臨時(shí)重定向 2.2,永久重定向 exec 4

    2023年04月25日
    瀏覽(25)
  • linux|shell編程|shell腳本內(nèi)的加減乘除運(yùn)算實(shí)現(xiàn)示例

    shell腳本內(nèi)的加減乘除是由于在編寫(xiě)kubernetes巡檢腳本的時(shí)候,某些部分需要做一點(diǎn)簡(jiǎn)單的運(yùn)算,突然發(fā)現(xiàn)我其實(shí)對(duì)這些不太熟悉。 因此,查閱了一些資料,現(xiàn)在就加減乘除運(yùn)算在shell腳本內(nèi)如何應(yīng)用做一個(gè)簡(jiǎn)單的總結(jié),寫(xiě)的不對(duì)的地方請(qǐng)各位輕點(diǎn)噴 首先,我們看一個(gè)錯(cuò)誤的示

    2024年02月17日
    瀏覽(19)
  • 【Linux命令行與Shell腳本編程】第十九章 正則表達(dá)式

    【Linux命令行與Shell腳本編程】第十九章 正則表達(dá)式

    正則表達(dá)式基礎(chǔ) 定義BRE模式 擴(kuò)展正則表達(dá)式 在sed和gawk中創(chuàng)建正則表達(dá)式,以得到所需的數(shù)據(jù)。 正則表達(dá)式是一種可供Linux工具過(guò)濾文本的自定義模板,使用元字符來(lái)描述數(shù)據(jù)流中的一個(gè)或多個(gè)字符. Linux工具(比如sed或gawk)會(huì)在讀取數(shù)據(jù)時(shí)使用正則表達(dá)式對(duì)數(shù)據(jù)進(jìn)行模式匹配

    2024年02月13日
    瀏覽(24)
  • Linux shell編程學(xué)習(xí)筆記14:編寫(xiě)和運(yùn)行第一個(gè)shell腳本hello world!

    Linux shell編程學(xué)習(xí)筆記14:編寫(xiě)和運(yùn)行第一個(gè)shell腳本hello world!

    ?* 20231020?寫(xiě)這篇博文斷斷續(xù)續(xù)花了好幾天,為了說(shuō)明不同shell在執(zhí)行同一腳本文件時(shí)的差別,我分別在csdn提供線上Linux環(huán)境 (使用的shell是zsh)和自己的電腦上(使用的shell是bash)做測(cè)試。功夫不負(fù)有心人,在其中一些實(shí)例中可以體現(xiàn)出zsh和bash的對(duì)腳本文件支持的差別,收

    2024年02月07日
    瀏覽(29)
  • lv3 嵌入式開(kāi)發(fā)-5 linux shell腳本編程(概念、變量、語(yǔ)句)

    lv3 嵌入式開(kāi)發(fā)-5 linux shell腳本編程(概念、變量、語(yǔ)句)

    ?Shell腳本是利用 shell 的功能所寫(xiě)的一個(gè)程序。這個(gè)程序是使用純文本文件,將一些 shell 的語(yǔ)法與命令(含外部命令)寫(xiě)在里面,搭配正則表達(dá)式、管道命令與數(shù)據(jù)流重定向等功能 ?第一個(gè)Shell腳本文件 變量來(lái)源于數(shù)學(xué),是計(jì)算機(jī)語(yǔ)言中能儲(chǔ)存計(jì)算結(jié)果或能表示值的抽象概念

    2024年02月10日
    瀏覽(56)
  • Linux Shell 腳本編程學(xué)習(xí)之【第2章 Linux文件系統(tǒng)和文本編輯器(第一部分)】

    1、root用戶 系統(tǒng)唯一,是真實(shí)的。該用戶既可以登錄系統(tǒng),可 以操作系統(tǒng)任何文件和命令,擁有最高權(quán)限。 2、虛擬用戶 這類用戶也被稱為偽用戶或假用戶,與真實(shí)用戶區(qū)分開(kāi)來(lái),這類用戶不 具有登錄系統(tǒng)的能力,但卻是系統(tǒng)運(yùn)行不可缺少的用戶,比如 bin、daemon、adm、 ft

    2024年02月16日
    瀏覽(26)
  • Linux Shell 腳本編程學(xué)習(xí)之【第3章 正則表達(dá)式 (第一部分)】

    1、正則表達(dá)式是由一串字符和元字符構(gòu)成的字符串,簡(jiǎn)稱 RE(Regular Expression)。 2、正則表達(dá)式起到數(shù)據(jù)過(guò)濾作用。 3、POSIX 標(biāo)準(zhǔn)將正則表達(dá)式分為兩類:基本的正則表達(dá)式和擴(kuò)展的正則表達(dá)式,大部分 Linux 應(yīng)用和工具僅支持基本的正則表達(dá)式。 Linux Shell 以一串字符作為表達(dá)式

    2024年02月16日
    瀏覽(24)

覺(jué)得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包