Linux shell脚本进阶使用如何巧妙结合长尾词实现高效自动化操作?

2026-04-11 07:251阅读0评论SEO资讯
  • 内容介绍
  • 文章标签
  • 相关推荐

本文共计2807个文字,预计阅读时间需要12分钟。

Linux shell脚本进阶使用如何巧妙结合长尾词实现高效自动化操作?

在Shell脚本中,`continue` 和 `break` 是两个用于控制循环执行的语句。

- `continue`:用于提前结束当前循环的本次迭代,并立即开始下一次迭代。- `break`:用于立即结束当前循环,不论当前迭代是否完成。

示例:shfor i in {1..5}do if [ $i -eq 3 ]; then continue fi echo Loop iteration $idone

echo Loop ended.

for i in {1..5}do if [ $i -eq 3 ]; then break fi echo Loop iteration $idone

echo Loop ended.

shell的循环控制语句

- continue:提前结束某次循环,重新开始下一次 - break:提前结束某层循环 范例:

#求100以内的奇数和 #!/bin/bash sum=0 for i in `seq 100`;do if [ $[i%2] -ne 0 ];then continue else let sum+=$i fi done echo $sum

#实现100以内的奇数和 #!/bin/bash sum=0 for i in `seq 100`;do #``:命令替换 if [ $[i%2] -eq 0 ];then #$[]:shell的算数语法 let sum+=$i #let工具需要借助一个变量存储计算后的值 fi done echo $sum shell的循环控制 shift 命令

每执行一次shift命令,都会左移一次。

#比如有三个参数$1 $2 $3,执行一次shift命令后,$1就删除了,$2变成$1,一次类推。 #!/bin/bash echo $* shift echo $* shift echo $* shift #输出结果: [root@Centos8 ~]# bash shift.sh 1 2 3 4 5 1 2 3 4 5 2 3 4 5 3 4 5

#利用shift的方式批量创建账号 #!/bin/bash if [$# -eq 0];then #判断位置参数是否是0 echo "请输入需要创建的用户" exit fi while [ "$1" ] ;do #[ "$1" ]:判断$1是否为空,只写字符串就表示字符串不为空,为真 if id $1 &> /dev/null; then #如果id命令执行的结果为真($?=0)就表示用户存在了 echo "$1 is exist" else useradd $1 echo "$1 is create" fi shift done echo "all user is create " #使用for的形式创建账号 if [$# -eq 0];then #判断位置参数是否是0 echo "请输入需要创建的用户" exit fi for user in $*;do if id $user &> /dev/null; then #如果id命令执行的结果为真($?=0)就表示用户存在了 echo "$user is exist" else useradd $user echo "$user is create" fi done echo "all user is create " while 特殊用法 while read

文本的逐行处理。

格式

while read line; do 循环体 done < /PATH/FROM/SOMEFILE

while read line ;do echo $line; done #标准输入,逐行处理 while read line ; do xxxx; done < filename #可以利用标准输入重定向把文件传给它 cat /etc/issue | while read line ;do echo $line; done #用管道 #使用while read判断磁盘分区磁盘的利用率 #!/bin/bash while true ; do #一直执行 df | sed -nr '/^\/dev\/sd/ s#([^ ]+).*([0-9]+)%.*#\1 \2#p' | while read DEV USE;do if [ $USE -gt 80 ];then echo "$DEV will be full, USE: $USE" else echo "$DEV is health, USE: $USE" fi done sleep 2 #每两秒执行一次 done #sed -nr '/^\/dev\/sd/ s#(^[^ ]+).*([0-9]+)%.*#\1 \2#p' | while read DEV USE;do #/^\/dev\/sd/ --- 以为/dev/sd开头的(非空格的内容) #[^ ]+ :取出分区的设备,非空格,一个以上的字符 #\1 \2 --- 后项替换

#查看/sbin/nologin的shell类型的用户名和UID #!/bin/bash while read line ; do #通过输入重定向的方式逐行处理内容 if [[ $line =~ /sbin/nologin$ ]];then # [[ =~ ]]:会把会把右边的字符串当成正则 echo $line | cut -d: -f1,3 # -d:指定分隔符 -f:取那几列 fi done < /etc/passwd 循环与菜单 select

帮助我们生成菜单的作用。

格式:

#语法和for的语法很类似 select 变量 in 列表 ;do 所作的操作 done #PS3用于输出提示信息,效果等同于 read -p #输入的信息保存到置变量REPLY中 #select 是个无限循环,因此要用 break 命令退出循环 #PS1:是影响我们当前提符的 #PS2:影响多行多定向(<<)提示符的 echo $PS2--> >

#列表就是用来生成菜单的 PS3="请选择功能(1-5):" #PS3:更改菜单的提示信息 select list in 升级软件 备份数据库 回滚软件 删库跑路 ; do echo $REPLY; done

#!/bin/bash PS3="请输入对应选项(1-5): " select menu in 安装 升级 配置 卸载;do case $REPLY in 1) echo "install" ;; 2) echo "update" ;; 3) echo "config" ;; 4) echo "remove" ;; *) echo "No this select" ;; esac done 函数:function 函数定义格式:

函数名 () { 函数体 } 或 function 函数 { 函数体 } #写了function关键词,可以省略函数名后面的括号 调用函数:直接通过函数名调用

函数名出现的地方,会被自动替换为函数代码

[root@centos8 ~]#dir() { > ls -l > } [root@centos8 ~]#dir #调用函数 total 4 函数文件:只存放函数的文件 调用函数文件

. filename 或 source filename #.和source等价 函数返回值

# 使用echo等命令进行输出 # 函数体中调用命令的输出结果 函数的参数

也是用$n等来实现的。

函数退出状态码

#1. 取决于最后一天命令的状态码 #2. 自定义状态码: retuen num #0:无错误返回,1-255:有错误返回 函数的变量

普通变量:变量名="值" #只能当前进程使用 环境变量:export 变量名="值" #当前进程和子进程都能使用 本地变量: local 变量名="值" #限定了变量在函数中有效,对外部的不影响 范例:

#判断操作系统类型安装软件 #!/bin/bash os_type { if cat /etc/os-release | grep -i -q "ubuntu" ; then # -q:不显示查找的结果,不管找到与否 echo "ubuntu" elif cat /etc/os-release | grep -E "centos" ;then echo "centos" else echo "no find ubuntu or centos" fi } if [ `os_type` = centos ] ;then #字符串用= != < > 等 (判断符号两边需要加上空格) yum install httpd -y elif [ `os_type` = ubuntu ] ; then apt install httpd -y else echo "nofind centos or ubuntu"

#粗略判断ip格式是否合法 ##/bin/bash is_ip () { if [[ "$1" =~ ^([0-9]{1,3}\.){3}[0-9]{1,3}$ ]] ;then echo "$1 is valid" else echo "$1 is not valid" fi } is_ip $1 #给函数传递参数 shell脚本的常用工具 shell脚本信号的捕捉:trap

trap:陷阱,用于捕获信号的

信号的类型:

使用trap -l可以查看

CTRL+C:发送的就是2(SIGINT)信号,程序收到这个信号以后就会退出。 shell脚本捕获信号

通过trap指令来完成:

#格式: #通过捕获信号来修改信号的原有功能 trap '捕获到信号以后要做的事' 信号 #信号可以是全称、缩写或者前面的数字标号 例如: trap '' 信号 #忽略信号操作 trap '-' 信号 #恢复信号原有的功能 shell脚本创建临时文件:mktemp

希望创建的临时文件和现有文件不冲突 #创建临时文件的格式 mktemp [选项] [模板] #模板就是临时文件的文件名 #模板格式: filenameXXX,文件前缀+三个随机字符(X(大写)至少要出现三个) 例如;mktemp fileXXX --->file90X #选项: -d:创建临时目录文件 -p:指定创建的位置 范例

#通过创建临时文件,实现文件垃圾箱(把不用的文件移动到一个目录里面) DIR=`mktemp -d /tmp/trash-$(date +%F_%H-%M-%S)XXXXXX` #创建一个临时目录文件 mv $* $DIR # $*:表示所有位置的参数 echo $* is move to $DIR 安装复制文件 install

install命令可以改权限、拷贝、创建文件夹等

Linux shell脚本进阶使用如何巧妙结合长尾词实现高效自动化操作?

#编译安装make install:把make命令执行的编译的结果复制到对应的文件中。make install 调用了install命令 #install 的用法(和cp命令很类似) #选项 -m MODE,默认755,修改权限 -o OWNER,指定所有者 -g GROUP,指定所有组 -d DIRNAME 目录,创建目录文件 ##例如 install -m 770 -d /testdir/installdir #创建一个权限为770的文件夹(install -d 相当于 mkdir -p) install -m 700 -o tom -g root /etc/issue /etc/xx.txt #复制一个文件到指定位置,复制的时候更改了权限 expect

把交互式的命令变成非交互式的。(espect通过对指定命令的监控,出现对应关键字的时候执行对应操作)

#expect中相关命令: spawn 监控某一个命令的执行 expect 捕获特定的字符串 send 捕获到这个特定字符串后,发送对应信息 interact 允许用户交互 exp_continue 匹配多个字符串在执行动作后加此命令 范例

#匹配到hi后,会输出“you said hi”,并换行 expect "hi" {send "You said hi\n"} #捕获屏幕上是否有hi,如果有就自动打印xx shell脚本的数组

数组:多个变量的集合

bash的数组支持稀疏格式 #索引不连续就叫做稀疏格式 数据的申明

建议先声明再使用。 #声明数组: declare -a 数据名 #申明为普通数组 declare -A 数组名 #申明为关联数组 #管理数组必须申明后再使用,且关联和普通不能转换 #声明变量 既然所有变量的默认类型是字符串型,那么只要我们把变量声明为整数型就可以进行运算了, # 定义变量b并赋值为3,具有整型属性。 declare -i x=3 数组赋值

#单个元素赋值 数组名[索引]=值 #例如:weekdays[0]="Sunday" #一次全部赋值:数组名=(v1,v2...vn) #范例:title=("ceo" "coo" "cto") #使用空格作为分隔符,而不是逗号 使用数组

${数组名[索引]} #引用数组所有元素 ${ARRAY_NAME[*]}或${ARRAY_NAME[@]} 删除数组

#删除数组中的某一个元素 unset 数组名[索引] #删除整个数组 unset 数组名 关联数组

下标不是默认的数字0..n,而是自定义的。

格式

数组名[自定义的下标]=值 #例如: aa[name1]=bob --- echo ${aa[name1]}--->bob 范例

#随机生成十个数字,找出最大的和最小的 #!/bin/bash max=0 min=0 declare -a arr #定义一个数组用于存储生成的是个随机数 i=0 while [ $i -le 10 ];do arr[$i]=$RANDOM #给数组赋值 if [ $i -eq 0 ];then #把第一个数作为基准来判断后续数的大小 max=${arr[$i]} min=${arr[$i]} else if [ ${arr[$i]} -gt $max ];then max=${arr[$i]} fi if [ ${arr[$i]} -lt $min ];then min=${arr[$i]} fi fi let i++ #let工具需要一个变量来接受变量的值 done echo "max is : $max , min is $min" shell的字符串处理 shell字符串切片

取出某个字符串中的部分内容。

#数组中显示数组元素的个数: ${#数组名} #获取字符串的长度 ${#var} 例如:str=jkfjafasfa --->10 #跳过字符串左边的几个 ${var:num} #num:表示需要跳过几个 #跳过字符串左边的几个,保留多少个 ${var:offset:number} #number表示要保留的长度 根据模式取字符串

#删左留右边 ${var#*word} #从左边开始找,一直找到word后,就把他们都删除掉(懒惰模式) ${var##*word} #从左边开始找,一直找到最右边的word后,就把他们都删除掉(贪婪模式) #范例: file="var/log/messages" ---echo ${file#*/}-->log/messages 字符串的查找和替换

#替换第一次匹配到的 ${var/pattern/substr} #替换所有匹配到的 ${var//pattern/substr} 删除指定的字符串

#删除掉第一次找到的 ${var/pattern} #删除所有找的的 ${var/pattern}

标签:

本文共计2807个文字,预计阅读时间需要12分钟。

Linux shell脚本进阶使用如何巧妙结合长尾词实现高效自动化操作?

在Shell脚本中,`continue` 和 `break` 是两个用于控制循环执行的语句。

- `continue`:用于提前结束当前循环的本次迭代,并立即开始下一次迭代。- `break`:用于立即结束当前循环,不论当前迭代是否完成。

示例:shfor i in {1..5}do if [ $i -eq 3 ]; then continue fi echo Loop iteration $idone

echo Loop ended.

for i in {1..5}do if [ $i -eq 3 ]; then break fi echo Loop iteration $idone

echo Loop ended.

shell的循环控制语句

- continue:提前结束某次循环,重新开始下一次 - break:提前结束某层循环 范例:

#求100以内的奇数和 #!/bin/bash sum=0 for i in `seq 100`;do if [ $[i%2] -ne 0 ];then continue else let sum+=$i fi done echo $sum

#实现100以内的奇数和 #!/bin/bash sum=0 for i in `seq 100`;do #``:命令替换 if [ $[i%2] -eq 0 ];then #$[]:shell的算数语法 let sum+=$i #let工具需要借助一个变量存储计算后的值 fi done echo $sum shell的循环控制 shift 命令

每执行一次shift命令,都会左移一次。

#比如有三个参数$1 $2 $3,执行一次shift命令后,$1就删除了,$2变成$1,一次类推。 #!/bin/bash echo $* shift echo $* shift echo $* shift #输出结果: [root@Centos8 ~]# bash shift.sh 1 2 3 4 5 1 2 3 4 5 2 3 4 5 3 4 5

#利用shift的方式批量创建账号 #!/bin/bash if [$# -eq 0];then #判断位置参数是否是0 echo "请输入需要创建的用户" exit fi while [ "$1" ] ;do #[ "$1" ]:判断$1是否为空,只写字符串就表示字符串不为空,为真 if id $1 &> /dev/null; then #如果id命令执行的结果为真($?=0)就表示用户存在了 echo "$1 is exist" else useradd $1 echo "$1 is create" fi shift done echo "all user is create " #使用for的形式创建账号 if [$# -eq 0];then #判断位置参数是否是0 echo "请输入需要创建的用户" exit fi for user in $*;do if id $user &> /dev/null; then #如果id命令执行的结果为真($?=0)就表示用户存在了 echo "$user is exist" else useradd $user echo "$user is create" fi done echo "all user is create " while 特殊用法 while read

文本的逐行处理。

格式

while read line; do 循环体 done < /PATH/FROM/SOMEFILE

while read line ;do echo $line; done #标准输入,逐行处理 while read line ; do xxxx; done < filename #可以利用标准输入重定向把文件传给它 cat /etc/issue | while read line ;do echo $line; done #用管道 #使用while read判断磁盘分区磁盘的利用率 #!/bin/bash while true ; do #一直执行 df | sed -nr '/^\/dev\/sd/ s#([^ ]+).*([0-9]+)%.*#\1 \2#p' | while read DEV USE;do if [ $USE -gt 80 ];then echo "$DEV will be full, USE: $USE" else echo "$DEV is health, USE: $USE" fi done sleep 2 #每两秒执行一次 done #sed -nr '/^\/dev\/sd/ s#(^[^ ]+).*([0-9]+)%.*#\1 \2#p' | while read DEV USE;do #/^\/dev\/sd/ --- 以为/dev/sd开头的(非空格的内容) #[^ ]+ :取出分区的设备,非空格,一个以上的字符 #\1 \2 --- 后项替换

#查看/sbin/nologin的shell类型的用户名和UID #!/bin/bash while read line ; do #通过输入重定向的方式逐行处理内容 if [[ $line =~ /sbin/nologin$ ]];then # [[ =~ ]]:会把会把右边的字符串当成正则 echo $line | cut -d: -f1,3 # -d:指定分隔符 -f:取那几列 fi done < /etc/passwd 循环与菜单 select

帮助我们生成菜单的作用。

格式:

#语法和for的语法很类似 select 变量 in 列表 ;do 所作的操作 done #PS3用于输出提示信息,效果等同于 read -p #输入的信息保存到置变量REPLY中 #select 是个无限循环,因此要用 break 命令退出循环 #PS1:是影响我们当前提符的 #PS2:影响多行多定向(<<)提示符的 echo $PS2--> >

#列表就是用来生成菜单的 PS3="请选择功能(1-5):" #PS3:更改菜单的提示信息 select list in 升级软件 备份数据库 回滚软件 删库跑路 ; do echo $REPLY; done

#!/bin/bash PS3="请输入对应选项(1-5): " select menu in 安装 升级 配置 卸载;do case $REPLY in 1) echo "install" ;; 2) echo "update" ;; 3) echo "config" ;; 4) echo "remove" ;; *) echo "No this select" ;; esac done 函数:function 函数定义格式:

函数名 () { 函数体 } 或 function 函数 { 函数体 } #写了function关键词,可以省略函数名后面的括号 调用函数:直接通过函数名调用

函数名出现的地方,会被自动替换为函数代码

[root@centos8 ~]#dir() { > ls -l > } [root@centos8 ~]#dir #调用函数 total 4 函数文件:只存放函数的文件 调用函数文件

. filename 或 source filename #.和source等价 函数返回值

# 使用echo等命令进行输出 # 函数体中调用命令的输出结果 函数的参数

也是用$n等来实现的。

函数退出状态码

#1. 取决于最后一天命令的状态码 #2. 自定义状态码: retuen num #0:无错误返回,1-255:有错误返回 函数的变量

普通变量:变量名="值" #只能当前进程使用 环境变量:export 变量名="值" #当前进程和子进程都能使用 本地变量: local 变量名="值" #限定了变量在函数中有效,对外部的不影响 范例:

#判断操作系统类型安装软件 #!/bin/bash os_type { if cat /etc/os-release | grep -i -q "ubuntu" ; then # -q:不显示查找的结果,不管找到与否 echo "ubuntu" elif cat /etc/os-release | grep -E "centos" ;then echo "centos" else echo "no find ubuntu or centos" fi } if [ `os_type` = centos ] ;then #字符串用= != < > 等 (判断符号两边需要加上空格) yum install httpd -y elif [ `os_type` = ubuntu ] ; then apt install httpd -y else echo "nofind centos or ubuntu"

#粗略判断ip格式是否合法 ##/bin/bash is_ip () { if [[ "$1" =~ ^([0-9]{1,3}\.){3}[0-9]{1,3}$ ]] ;then echo "$1 is valid" else echo "$1 is not valid" fi } is_ip $1 #给函数传递参数 shell脚本的常用工具 shell脚本信号的捕捉:trap

trap:陷阱,用于捕获信号的

信号的类型:

使用trap -l可以查看

CTRL+C:发送的就是2(SIGINT)信号,程序收到这个信号以后就会退出。 shell脚本捕获信号

通过trap指令来完成:

#格式: #通过捕获信号来修改信号的原有功能 trap '捕获到信号以后要做的事' 信号 #信号可以是全称、缩写或者前面的数字标号 例如: trap '' 信号 #忽略信号操作 trap '-' 信号 #恢复信号原有的功能 shell脚本创建临时文件:mktemp

希望创建的临时文件和现有文件不冲突 #创建临时文件的格式 mktemp [选项] [模板] #模板就是临时文件的文件名 #模板格式: filenameXXX,文件前缀+三个随机字符(X(大写)至少要出现三个) 例如;mktemp fileXXX --->file90X #选项: -d:创建临时目录文件 -p:指定创建的位置 范例

#通过创建临时文件,实现文件垃圾箱(把不用的文件移动到一个目录里面) DIR=`mktemp -d /tmp/trash-$(date +%F_%H-%M-%S)XXXXXX` #创建一个临时目录文件 mv $* $DIR # $*:表示所有位置的参数 echo $* is move to $DIR 安装复制文件 install

install命令可以改权限、拷贝、创建文件夹等

Linux shell脚本进阶使用如何巧妙结合长尾词实现高效自动化操作?

#编译安装make install:把make命令执行的编译的结果复制到对应的文件中。make install 调用了install命令 #install 的用法(和cp命令很类似) #选项 -m MODE,默认755,修改权限 -o OWNER,指定所有者 -g GROUP,指定所有组 -d DIRNAME 目录,创建目录文件 ##例如 install -m 770 -d /testdir/installdir #创建一个权限为770的文件夹(install -d 相当于 mkdir -p) install -m 700 -o tom -g root /etc/issue /etc/xx.txt #复制一个文件到指定位置,复制的时候更改了权限 expect

把交互式的命令变成非交互式的。(espect通过对指定命令的监控,出现对应关键字的时候执行对应操作)

#expect中相关命令: spawn 监控某一个命令的执行 expect 捕获特定的字符串 send 捕获到这个特定字符串后,发送对应信息 interact 允许用户交互 exp_continue 匹配多个字符串在执行动作后加此命令 范例

#匹配到hi后,会输出“you said hi”,并换行 expect "hi" {send "You said hi\n"} #捕获屏幕上是否有hi,如果有就自动打印xx shell脚本的数组

数组:多个变量的集合

bash的数组支持稀疏格式 #索引不连续就叫做稀疏格式 数据的申明

建议先声明再使用。 #声明数组: declare -a 数据名 #申明为普通数组 declare -A 数组名 #申明为关联数组 #管理数组必须申明后再使用,且关联和普通不能转换 #声明变量 既然所有变量的默认类型是字符串型,那么只要我们把变量声明为整数型就可以进行运算了, # 定义变量b并赋值为3,具有整型属性。 declare -i x=3 数组赋值

#单个元素赋值 数组名[索引]=值 #例如:weekdays[0]="Sunday" #一次全部赋值:数组名=(v1,v2...vn) #范例:title=("ceo" "coo" "cto") #使用空格作为分隔符,而不是逗号 使用数组

${数组名[索引]} #引用数组所有元素 ${ARRAY_NAME[*]}或${ARRAY_NAME[@]} 删除数组

#删除数组中的某一个元素 unset 数组名[索引] #删除整个数组 unset 数组名 关联数组

下标不是默认的数字0..n,而是自定义的。

格式

数组名[自定义的下标]=值 #例如: aa[name1]=bob --- echo ${aa[name1]}--->bob 范例

#随机生成十个数字,找出最大的和最小的 #!/bin/bash max=0 min=0 declare -a arr #定义一个数组用于存储生成的是个随机数 i=0 while [ $i -le 10 ];do arr[$i]=$RANDOM #给数组赋值 if [ $i -eq 0 ];then #把第一个数作为基准来判断后续数的大小 max=${arr[$i]} min=${arr[$i]} else if [ ${arr[$i]} -gt $max ];then max=${arr[$i]} fi if [ ${arr[$i]} -lt $min ];then min=${arr[$i]} fi fi let i++ #let工具需要一个变量来接受变量的值 done echo "max is : $max , min is $min" shell的字符串处理 shell字符串切片

取出某个字符串中的部分内容。

#数组中显示数组元素的个数: ${#数组名} #获取字符串的长度 ${#var} 例如:str=jkfjafasfa --->10 #跳过字符串左边的几个 ${var:num} #num:表示需要跳过几个 #跳过字符串左边的几个,保留多少个 ${var:offset:number} #number表示要保留的长度 根据模式取字符串

#删左留右边 ${var#*word} #从左边开始找,一直找到word后,就把他们都删除掉(懒惰模式) ${var##*word} #从左边开始找,一直找到最右边的word后,就把他们都删除掉(贪婪模式) #范例: file="var/log/messages" ---echo ${file#*/}-->log/messages 字符串的查找和替换

#替换第一次匹配到的 ${var/pattern/substr} #替换所有匹配到的 ${var//pattern/substr} 删除指定的字符串

#删除掉第一次找到的 ${var/pattern} #删除所有找的的 ${var/pattern}

标签: