IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 系统运维 -> Linux Shell编程 -> 正文阅读

[系统运维]Linux Shell编程

目录

1 基础正则表达式

1.1 正则表达式与通配符

1.2 基础正则表达式

1.3 正则表达式练习

2 字符截取命令

2.1 cut字段提取命令

2.1.1 cut命令的局限

2.2 printf命令

2.2.1 print和printf命令

2.3 awk命令

2.3.1 BEGIN

2.3.2 END

2.3.3 FS内置变量

2.3.4 关系运算符

2.4 sed命令

3 字符处理命令

3.1 排序命令sort

3.2 统计命令wc

4 条件判断

4.1 判断文件类型

4.2 判断文件权限

4.3 比较文件

4.4 比较整数

4.5 判断字符串

4.6 多重条件判断

5 流程控制

5.1 if语句

5.1.1 单分支if条件语句

5.1.2 双分支if条件语句

5.1.3 多分支if条件语句

5.2 case语句

5.3 for循环

5.3.1 语法一

5.3.2 语法二

5.4 while循环与until循环

5.4.1 while循环

5.4.2 until循环

6 函数


1 基础正则表达式

1.1 正则表达式与通配符

  • 正则表达式用来在文件中匹配符合条件的字符串,正则是包含匹配。grep、awk、sed等命令可以支持正则表达式。

  • 通配符用来匹配符合条件的文件名,通配符是完全匹配。ls、find、cp这些命令不支持正则表达式,所以只能使用shell自己的通配符来进行匹配了。

1.2 基础正则表达式

1.3 正则表达式练习

练习准备:创建一个名为“test_rule.txt”的文件,内容如下:

Mr. Li Ming said:
he was the honcst man in LampBrother.
123despise him.

But since Mr. shen Chao came,
he never saaaid those words.
5555nice!

because, actuaaaally,
Mr. Shen Chao is the most honest man!

Later,Mr. Li ming soid his hot body.
  • “*”前一个字符匹配0次,或任意多次

grep "a*" test_rule.txt ? ?# 匹配所有内容,包括空白行

grep "aa*" test_rule.txt ? ?# 匹配至少包含有一个a的行

grep "aaa*" test_rule.txt ? ?# 匹配最少包含两个连续a的字符串

grep "aaaaa*" test_rule.txt ? ?# 则会匹配最少包含四个个连续a的字符串

  • “.” 匹配除了换行符外任意一个字符

grep "s..d" test_rule.txt? ??# “s..d”会匹配在s和d这两个字母之间一定有两个字符的单词

grep "s.*d" test_rule.txt? ??# 匹配在s和d字母之间有任意字符

grep ".*" test_rule.txt? ??# 匹配所有内容

  • “^”匹配行首,“$”匹配行尾

grep "^M" test_rule.txt? ??# 匹配以大写“M”开头的行

grep "n$" test_rule.txt? ??# 匹配以小写“n”结尾的行

grep -n "^$" test_rule.txt? ??# 会匹配空白行

  • “[]” 匹配中括号中指定的任意一个字符,只匹配一个字符

grep "s[ao]id" test_rule.txt? ??# 匹配s和i字母中,要不是a、要不是o

grep "[0-9]" test_rule.txt? ??# 匹配任意一个数字

grep "^[a-z]" test_rule.txt? ??# 匹配用小写字母开头的行

  • “[^]” 匹配除中括号的字符以外的任意一个字符

grep "^[a-z]" test_rule.txt? ??# 匹配不用小写字母开头的行

grep "^[a-zA-Z]" test_rule.txt? ??# 匹配不用字母开头的行 “\” 转义符

grep "\.$" test_rule.txt? ??# 匹配使用“.”结尾的行

  • “\{n\}”表示其前面的字符恰好出现n次

grep "a\{3\}" test_rule.txt? ??# 匹配a字母连续出现三次的字符串

grep "[0-9]\{3\}" test_rule.txt? ??# 匹配包含连续的三个数字的字符串

  • “\{n,\}”表示其前面的字符出现不小于n次

grep "^[0-9]\{3,\}[a-z]" test_rule.txt? ??# 匹配最少用连续三个数字开头的行

  • “\{n,m\}”匹配其前面的字符至少出现n次,最多出现m次

grep "sa\{1,3\}i" test_rule.txt? ??# 匹配在字母s和字母i之间有最少一个a,最多三个a

2 字符截取命令

2.1 cut字段提取命令

命令格式:cut [选项] 文件名

选项:

  • -f 列号: 提取第几列
  • -d 分隔符: 按照指定分隔符分割列(默认以“\t”为分隔符)

练习文件:创建一个名为“student.txt”的文件,内容如下

ID	Name	gender	Mark
1	Liming	M	86
2	Sc	M	90
3	Gao	M	83

cut -f 2 student.txt? ? #?提取第二列

cut -f 2,3 student.txt? ??# 提取第二第三列

cut -d ":" -f 1,3 /etc/passwd? ??# 以“:”为分隔符提取第一第三列

2.1.1 cut命令的局限

df -h | cut -d " " -f 5? ? # 提取“已用%”列数据

注意:有多个空格时提取会出问题

2.2 printf命令

命令格式:printf ’输出类型输出格式’ 输出内容

输出类型:

  • %ns : 输出字符串。n是数字指代输出几个字符
  • %ni : 输出整数。n是数字指代输出几个数字
  • %m.nf : 输出浮点数。m和n是数字,指代输出的整数 位数和小数位数。如%8.2f代表共输出8位数, 其中2位是小数,6位是整数。

输出格式:

  • \a : 输出警告声音
  • \b : 输出退格键,也就是Backspace键
  • \f : 清除屏幕
  • \n : 换行
  • \r : 回车,也就是Enter键
  • \t : 水平输出退格键,也就是Tab键
  • \v : 垂直输出退格键,也就是Tab键

练习1:

printf %s 1 2 3 4 5 6

printf %s %s %s 1 2 3 4 5 6

printf '%s %s %s' 1 2 3 4 5 6

printf '%s %s %s\n' 1 2 3 4 5 6

小贴士:三个看成一个整体所以123是一个整体,456是另一个。所以在3后面换行

练习2:创建一个名为“student.txt”的文件,内容如下

ID Name PHP Linux MySQL Average
1 Liming 82 95 86 87.66
2 Sc 74 96 87 85.66
3 Gao 99 83 93 91.66

printf '%s' $(cat student.txt)? ? # 不调整输出格式

printf '%s\t %s\t %s\t %s\t %s\t %s\t \n' $(cat student.txt)? ??# 调整格式输出

2.2.1 print和printf命令

在awk命令的输出中支持print和printf命令

  • print:print会在每个输出之后自动加入一个换行符(Linux默认没有print命令)

  • printf:printf是标准格式输出命令,并不会自动加入换行符,如果需要换行,需要手工加入换行符

2.3 awk命令

命令格式:awk ‘条件1{动作1} 条件2{动作2}…’ 文件名

条件(Pattern):

  • 一般使用关系表达式作为条件
  • x > 10 判断变量 x是否大于10
  • x>=10 大于等于
  • x<=10 小于等于

动作(Action):

  • 格式化输出
  • 流程控制语句
  • awk '{printf $2 "\t" $6 "\n"}' student.txt? ? # 格式化输出第2、6列内容

  • df -h | grep /dev/sda2 | awk '{printf $5 "\n"}' | cut -d "%" -f 1? ? # 获取根目录的内存占用率

2.3.1 BEGIN

说明:在命令开始前执行

  • awk 'BEGIN{printf "This is a transcript \n" } {printf $2 "\t" $6 "\n"}' student.txt? ? # 在标准化输出前输出“This is a transcript \n”

2.3.2 END

说明:在命令执行结束后执行

  • awk 'END{printf "The End \n" } {printf $2 "\t" $6 "\n"}' student.txt? ? # 在标准化输出结束后输出“The End \n”

2.3.3 FS内置变量

说明:指定分隔符

  • cat /etc/passwd | grep "/bin/bash" | awk 'BEGIN {FS=":"} {printf $1 "\t" $3 "\n"}'

小贴士:如果不在{FS=":"} 前边加“BEGIN”,第一行会有问题

2.3.4 关系运算符

  • cat student.txt | grep -v Name | awk '$6 >= 87 {printf $2 "\n" }'

2.4 sed命令

sed 是一种几乎包括在所有 UNIX 平台(包括 Linux)的轻量级流编辑器。sed主要是用来将数据进行选取、替换、删除、新增的命令。

命令格式:sed [选项] ‘[动作]’ 文件名

选项:

  • -n: 一般sed命令会把所有数据都输出到屏幕 , 如果加入此选择,则只会把经过 sed命令处 理的行输出到屏幕。
  • -e: 允许对输入数据应用多条sed命令编辑
  • -i: 用sed的修改结果直接修改读取数据的文件, 而不是由屏幕输出

动作:

  • a \: 追加,在当前行后添加一行或多行。添加多行时,除最后 一行 外,每行末尾需要用“\”代 表数据未完结。
  • c \: 行替换,用c后面的字符串替换原数据行,替换多行时,除最 后一行外,每行末尾需“\”代 表数据未完结。
  • i \: 插入,在当期行前插入一行或多行。插入多行时,除最后 一行 外,每行末尾需要“\”代
  • 表数据未完结。
  • d: 删除,删除指定的行。
  • p: 打印,输出指定的行。
  • s: 字串替换,用一个字符串替换另外一个字符串。格式为“行范 围s/旧字串/新字串/g”(和vim中的替换格式类似)。

常用命令

行数据操作

  • sed '2p' student.txt? ??# 查看文件的第二行
  • sed -n '2p' student.txt? ??# 只查看文件的第二行
  • sed '2,3d' student.txt? ? # 删除第二行到第三行的数据,但不修改文件本身
  • sed '2a hello' student.txt? ? # 在第二行后追加hello
  • sed '2i hello world' student.txt? ??# 在第二行前插入两行数据
  • sed '2c No such person' student.txt? ??# 将第2行数据进行替换

字符串替换:sed ‘s/旧字串/新字串/g’ 文件名

  • sed '3s/74/99/g' student.txt? ? # 在第三行中,把74换成99
  • sed -i '3s/74/99/g' student.txt? ? # sed操作的数据直接写入文件(不建议)
  • sed -e 's/Liming//g ; s/Gao//g' student.txt? ? # 同时把“Liming”和“Gao”替换为空

3 字符处理命令

3.1 排序命令sort

命令格式:sort [选项] 文件名

选项:

  • -f: 忽略大小写
  • -n: 以数值型进行排序,默认使用字符串型排序
  • -r: 反向排序
  • -t: 指定分隔符,默认是分隔符是制表符
  • -k n[,m]: 按照指定的字段范围排序。从第n字段开始, m字段结束(默认到行尾)

常用命令

sort /etc/passwd? ??# 排序用户信息文件

sort -r /etc/passwd? ?# 反向排序

sort -t ":" -k 3,3 /etc/passwd? ? # 指定分隔符是“:”,用第三字段开头,第三字段结尾排序,就是只用第三字段排序

sort -n -t ":" -k 3,3 /etc/passwd? ? #?以数值型进行排序

3.2 统计命令wc

命令格式:wc [选项] 文件名

选项:

  • -l: 只统计行数
  • -w: 只统计单词数
  • -m: 只统计字符数

常用命令

wc -l /etc/passwd? ??#?统计文件行数

wc -w?/etc/passwd? ?# 统计文件单词数

df -h | wc? ? # 统计命令结果行数

4 条件判断

两种判断格式

  • test -e /root/install.log
  • [ -e /root/install.log ]

小贴士:

????????一般用第二种格式,且需要注意中括号[]与命令之间一定要有空格,否则会报错。

? ? ? ? echo $?? ? # 查看上一条命令结果:0为执行正确;非0为执行错误

4.1 判断文件类型

  • [ -d /root ] && echo "yes" || echo "no"? ? # 第一个判断命令如果正确执行,则打印“yes”,否则打印“no”

4.2 判断文件权限

  • [ -w student.txt ] && echo "yes" || echo "no"? ??# 判断文件是拥有写权限的

小贴士:只有该文件拥有写权限就返回真,无法判断具体用户是否拥有写权限

4.3 比较文件

  • ln /root/student.txt /tmp/stu.txt? ? #?创建个硬链接
  • [ /root/student.txt -ef /tmp/stu.txt ] && echo "yes" || echo "no" yes? ? # 用test进行测试

4.4 比较整数

  • [ 23 -ge 22 ] && echo "yes" || echo "no"? ? # 判断23是否大于等于22,当然是了
  • [ 23 -le 22 ] && echo "yes" || echo "no"? ? # 判断23是否小于等于22,当然不是了

4.5 判断字符串

常用命令

name=sc? ??# 给name变量赋值

[ -z "$name" ] && echo "yes" || echo "no"? ??#判断name变量是否为空,因为不为空,所以返回no

aa=11

bb=22? ? # 给变量aa和变量bb赋值

[ "$aa" == "$bb" ] && echo "yes" || echo "no"? ??#判断两个变量的值是否相等,明显不相等,所以返回no

4.6 多重条件判断

常用命令

aa=11

[ -n "$aa" -a "$aa" -gt 23 ] && echo "yes" || echo "no"? ??#判断变量aa是否有值,同时判断变量aa的是否大于23

[ -n "$aa" -a "$aa" -lt 23?] && echo "yes" || echo "no"

5 流程控制

5.1 if语句

5.1.1 单分支if条件语句

if  [ 条件判断式 ] ; then
    程序 
fi  
#或者
if  [ 条件判断式 ]  
    then
        	程序 
fi 

单分支条件语句需要注意几个点

  • if语句使用fi结尾,和一般语言使用大括号结尾不同

  • [ 条件判断式 ]就是使用test命令判断,所以中括号和条件判断式之间必须有空格

  • then后面跟符合条件之后执行的程序,可以放在[]之后,用“;”分割。也可以换行写入,就不需要“;”了

案例:判断分区使用率

#!/bin/bash
# 统计根分区使用率
# Author: Apollo

rate=$(df -h | grep "/dev/sda2" | awk '{print $5}' | cut -d "%" -f 1)
# 把根分区使用率作为变量值赋予变量rate
if [ $rate -ge 10 ]
        then
                echo "Warning! /dev/sda3 is full!"
fi

5.1.2 双分支if条件语句

if [ 条件判断式 ] 
	then   
		条件成立时,执行的程序  
else 
	条件不成立时,执行的另一个程序 
fi

案例1:备份配置目录/etc

#!/bin/bash
#备份配置目录/etc。
# Author:Apollo

ntpdate asia.pool.ntp.org &> /dev/null
#同步系统时间

date=$(date +%Y%m%d)
#把当前系统时间按照“年月日”格式赋予变量

datesize=$(du -sh /etc)
#统计配置目录/etc的大小,并把大小赋予size变量

if [ -d /tmp/etc_bak ]
    then
        echo "Date:$date!" > /tmp/etc_bak/etc_info.txt
        echo "Datasize:$size" >> /tmp/etc_bak/etc_info.txt
        cd /tmp/etc_bak
        tar -zcf etc-$date.tar.gz /etc etc_info.txt &> /dev/null
        rm -rf /tmp/etc_bak/etc_info.txt
    else
        mkdir /tmp/etc_bak
        echo "Date:$date!" > /tmp/etc_bak/etc_info.txt
        echo "Datasize:$size" >> /tmp/etc_bak/etc_info.txt
        cd /tmp/etc_bak
        tar -zcf etc-$date.tar.gz /etc etc_info.txt &> /dev/null
        rm -rf /tmp/etc_bak/etc_info.txt
fi

案例2:判断apache是否启动

#!/bin/bash
#Author:Apollo

port=$(nmap -sT 192.168.31.222 | grep 80/tcp | grep http | awk '{print $2}')
#使用nmap命令扫描服务器,并截取apache服务的状态,赋予变量port

echo ${port}

if [ "$port" == "open" ]
    then
        echo "$(date) httpd is ok!" >> /tmp/autostart-acc.log
else
	/usr/sbin/httpd -k start &> /dev/null
	echo "$(date) restart httpd!!" >> /tmp/autostart-err.log
fi

5.1.3 多分支if条件语句

if [ 条件判断式1 ]
    then
        当条件判断式1成立时,执行程序1
elif [ 条件判断式2 ]
    then
        当条件判断式2成立时,执行程序2
...省略更多条件...
else
    当所有条件都不成立时,最后执行此程序
fi

案例:

#!/bin/bash
#判断用户输入的是什么文件
#Author:Apollo

read -p "Please input a file name: " file
#接收键盘的输入,并赋予变量file

if [ -z "$file" ]
#判断file变量是否为空       
    then
        echo "Error, please input a file name"
        exit 1
elif [ ! -e "$file" ]
#判断file的值是否存在
    then
        echo "You input is not a file!"
        exit 2
elif [ -f "$file" ]
#判断file的值是否为普通文件
    then 
    echo "$file is a regulare file!"
elif [ -d "$file" ]
#判断file的值是否为目录文件  
    then
        echo "$file is a directory!"
else
    echo"$file is another file!"
fi

5.2 case语句

case语句和if…elif…else语句一样都是多分支条件语句,不过和if多分支条件语句不同的是,case语句只能判断一种条件关系,而if语句可以判断多种条件关系。

多分支case条件语句

case $变量名 in  
	"值1")   
		如果变量的值等于值1,则执行程序1   
		;;
	"值2")   
		如果变量的值等于值2,则执行程序2  
		;;		
		
	…省略其他分支…
	
	* )   
		如果变量的值都不是以上的值,则执行此程序 
		;;
esac

案例:

#!/bin/bash
#判断用户输入
#Author:Apollo

read -p 'Please chose "yes"/"no":' -t 30 cho

case $cho in
	"yes")
		echo "Your choice is yes!"
		;;
	"no")
		echo "Your choice is no!"
		;;
	*)
		echo "Your choice is error!"
		;;
esac

5.3 for循环

5.3.1 语法一

这种情况适用于不知道循环次数

for 变量 in 值1 值2 值3
	do 
		程序
	done

案例1:

#!/bin/bash
#for循环输出
#Author:Apollo

for city in beijing nanjing shanghai 
	do
		echo "this city is $city "
	done

案例2:

#!/bin/bash
#批量打包脚本
#Author:Apollo

cd /root/sh
ls *.sh > ls.log
for i in $(cat ls.log)
    do
       tar -zcf $i.tar.gz $i &> /dev/null
    done 
rm -rf ls.log

5.3.2 语法二

这种情况适用于知道循环次数

for (( 初始值;循环控制条件;变量变化 ))
	do
		程序
	done

案例1:

#!/bin/bash
#从1加到100
#Author:Apollo

num=0
for(( i=1;i<=100;i++ ))
	do
		num=$(( $num+$i ))
	done
echo "this sum of 1+2+...+100 is: $num"

案例2:

#!/bin/bash
#Author:Apollo
#批量添加新用户

read -p "Please input user name: " -t 30 name  # 输入用户名,等待时间30s
read -p "Please input the number of users: " -t 30 num  # 输入创建用户个数,等待时间30s
read -p "Please input the password of users: " -t 30 pass  # 输入用户密码,等待时间30s

if [ ! -z "$name" -a ! -z "$num" -a ! -z "$pass" ]  # 判断输入信息是否为空 
	then
		y=$(echo $num | sed s/[0-9]//g)  # 这里是判断输入的用户个数是否为数字,sed后也可以把s/[0-9]//g换为^[0-9]*$
			if [ -z "$y" ]	# 如果上一条语句输出不为空,就是输入的用户个数为数字,继续执行
				then
					for ((i=1;i<=$num;i++))  # 开始循环
						do
							/usr/sbin/useradd "$name$i" &>/dev/null  # 建立用户
							echo $pass | /usr/bin/passwd --stdin "$name$i" &>/dev/null  #设置用户密码,与用户名相同
						done
					echo "Build seccees!"
			fi
fi

5.4 while循环与until循环

5.4.1 while循环

while循环是不定循环,也称作条件循环。只要条件判断式成立,循环就会一直继续,直到条件判断式不成立,循环才会停止。这就和for的固定循环不太一样了。

while [ 条件判断式 ]
	do
		程序
	done

案例:从1加到100

#!/bin/bash
#从1加到100
#Author:shenchao(E-mail:shenchao@lampbrother.net)
i=1
s=0
while [ $i -le 100 ] 
#如果变量i的值小于等于100,则执行循环
    do
        s=$(($s+$i))
        i=$(($i+1))
    done
echo"Thesumis:$s"

5.4.2 until循环

until循环,和while循环相反,until循环时只要条件判断式不成立则进行循环,并执行循环程序。一旦循环条件成立,则终止循环。

until [ 条件判断式 ]
	do
		程序
	done

案例:从1加到100

#!/bin/bash
#从1加到100
#Author:Apollo

i=1
s=0
until [ $i -gt 100 ]
#循环直到变量i的值大于100,就停止循环
	do
		s=$(( $s+$i ))
		i=$(( $i+1 ))
	done
echo"The sum is: $s"

6 函数

[ function ] funname [()]{
    action;
    [return int;]
}

小贴士:

  • [] -> 表示可以省略
  • 在以上的函数语法中,前面的funcation 表示声明一个函数!!! 可以不写
  • return -n 是指退出函数

案例:

#!/bin/bash
funWithReturn(){
	echo "这个函数会对输入的两个数字进行相加运算..."
	echo "输入第一个数字: "
	read a
	echo "输入第二个数字: "
	read b
	echo "两个数字分别为 $a 和 $b !"
	return $(( $a+$b ))
}

funWithReturn

echo "输入的两个数字之和为 $? !"

  系统运维 最新文章
配置小型公司网络WLAN基本业务(AC通过三层
如何在交付运维过程中建立风险底线意识,提
快速传输大文件,怎么通过网络传大文件给对
从游戏服务端角度分析移动同步(状态同步)
MySQL使用MyCat实现分库分表
如何用DWDM射频光纤技术实现200公里外的站点
国内顺畅下载k8s.gcr.io的镜像
自动化测试appium
ctfshow ssrf
Linux操作系统学习之实用指令(Centos7/8均
上一篇文章      下一篇文章      查看所有文章
加:2022-06-23 01:01:37  更:2022-06-23 01:01:54 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/19 1:44:36-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码