当前位置: 首页 > ds >正文

Shell脚本入门:从零到精通

一、Shell脚本

1.什么是Shell?

Shell是用户与操作系统内和交互的桥梁,它既是命令行解释器,也是脚本编程语言,通过可以实现系统监控、批量处理、定时任务等操作。常见的Shell解释器有Bash(Linux默认)、Zsh、Fish等。

2.什么是Shell脚本?

通过Shell解释器运行,将多个系统命令与逻辑控制语句组合,实现批量操作或系统管理任务,是一种用于自动化执行命令序列的文本文件,有Shell命令、变量、函数和控制结构组成,扩展名为.sh。

3.简单Shell脚本设计

本机快速搭建Yum仓库

#vim yum.sh
#!/bin/bash
echo "[xx]           #将配置文件内容重定向到配置文件
name=xx
baseurl=xxx
enabled=1
gpgcheck=0" > /etc/yum.repos.d/xx.repo
#chmod +x yum.sh        #添加可执行权限
#./yum.sh        #执行脚本

本机快速搭建ftp服务

#vim ftp.sh
#!/bin/bash
yum -y install vsftpd &> /dev/null     #把无用信息丢弃
systemctl enabled vsftpd --now        #设置开机自启
#chmod +x ftp.sh
#./ftp.sh

二、Shell变量

1.变量的设置和取消

变量是用固定名称存储的可变数值,它能增强脚本对任务需求和运行环境的适应性,并便于在脚本中重复调用。

定义/赋值变量

变量名=变量值
例 X=10

查看变量

echo $变量名
echo ${变量名}
例:echo $X 
echo ${X}yuan       #变量名易混淆时,以{}界定

取消变量

unset 变量名       #手动取消
例:unset X
2.变量的种类
(1)按使用类型分类

环境变量:变量名通常都是大写,由系统维护,用来设置工作环境,只有个别变量的用户可以直接更改。

位置变量:bash内置,存储执行脚本时提供的参数。

预定义变量:bash内置,一类有特殊用途的变量,可以直接调用但不能直接赋值或修改。

自定义变量:由用户自主设置、修改及使用。

(2)环境变量

在配置文件/etc/profile对所有用户有效、~/.bash_profile仅对指定用户有效

env:列出所有环境变量

set:列出所有变量

境变量USER记录了用户名、HOME记录了家目录、SHELL记录了登录解释器、HOSTNAME记录主机名、UID是用户的id号

(3)预定义变量

$0:当前所在的进程或脚本名

$$:当前运行进程的进程号

$?:命令执行后的返回状态,0表示正常,1或其他表示异常

$#:已加载的位置变量的个数

$*:所有位置变量的值

(4)位置变量

再执行脚本时提供的命令行参数$n

3.变量的扩展应用
(1)三种引号对赋值的影响

双引号可以界定一个完整的字符串。

变量名="值1 值2 ..."
例:X="a a a"

单引号可以界定一个完整的字符串,并且可以实现屏蔽特殊符号的功能。

echo '$X'

反撇号或$(),可以将命令执行结果作为字符串存储。

变量名=`执行命令`
变量名=$(执行命令)
例:a=$(date)
(2)read标准输入取值

read从键盘读入变量值完成赋值,ssty -echo将回显功能关闭,ssty echo将回显功能恢复。

read -p "提示信息" 变量名
(3)变量的作用范围

局部变量:定义的变量默认只在当前Shell环境下有效,无法在子Shell环境中使用。

全局变量:能在当前Shell及子Shell环境中均有效,使用export可将局部变量声明为全局变量。

三、数值运算

1.整数运算
(1)$(())或$[]表达式

引用变量可省略$符号,计算结果替换表达式本身。

echo $[1+1]
echo $[1*1]
echo $[3-1]
echo $((10%3))
echo $((10/2))
(2)变量的自增自减

let命令可以直接对变量值做运算再保存新的值。

let i++
let i--
let += 1
let -=1
let i*=2
let i/=2
let i%=2
2.小数运算

将需要运算的表达式通过管道操作交给bc运算。注意,小数位的长度可采用scale=N限制。

echo "scale=2;$i * 10" | bc        #多表达式
echo "$A <= $B" | bc     #小数比较,返回结果为1则表达式成立,否则返回结果为0

四、条件测试

使用test 表达式 或者 [ 表达式 ]可以进行条件测试,中间空格不能省略,条件测试本身不显示任何信息,可以在测试后查看$?的值来判断。

1.字符串比较
(1)判断变量是否为空

[ 操作符 字符串]

-z 字符串的值为空

-n 字符串的值不为空(相当于!-n)

x=10
[ -z "$x" ]      #判断x是为空
echo $?           #查看上一次代码执行结果
[ -n "$x" ]      #判断x非空
echo $?          #查看结果
(2)判断字符串是否相等

[ 字符串1 操作符 字符串2 ]

== 两个字符串相同

!= 两个字串不相同

a=test
b=test
[ "$a" == "$b" ] && echo Y || echo N      #仅当判断结果正确时,执行echo Y,否则执行echo N
b=text
[ "$a" != "$b" ] && echo Y || echo N      
2.整数值比较

参与比较的必须是整数,可以调用变量。

[ 5 -gt 10 ] && echo Y || echo N     #大于
[ 5 -ge 3 ] && echo Y || echo N      #大于或等于
[ 2 -lt 3 ] && echo Y || echo N      #小于
[ 3 -le 3 ] && echo Y || echo N      #小于或等于
[ 5 -eq 5 ] && echo Y || echo N      #相等
[ 10 -ne 10 ] && echo Y || echo N    #不相等

监控主机登录用户数量的脚本

#vim warn.sh
#!/bin/bash
[ $(who | wc -l) ] -gt 5 ] $$ logger 当前主机登录人数超过5人!!!
#chmod +x warn.sh
#./warn.sh
#tail -2 /var/log/messages 
3.识别文件/目录状态

-e判断对象是否存在,无论是目录还是文件

[ -e "/etc" ] && echo Y || echo N

-d判断对象是否为目录

[ -d "/etc" ] && echo Y || echo N

-f判断对象是否为文件

[ -f "/etc" ] && echo Y || echo N

-r判断对象是否可读

[ -r "/etc/hosts" ] && echo Y || echo N

-w判断对象是否可写

[ -w "/etc/hosts" ] && echo Y || echo N

-x判断对象是否具有x权限

[ -x "/etc/hosts" ] && echo Y || echo N

五、判断结构

1.if选择结构

if单分支的语法组成:

if 测试条件;then命令序列
fi

if双分支的语法组成:

if 条件测试;then命令序列1
else命令序列2
fi

if多分支的语法组成:

if 条件测试1;then命令序列1
elif 条件测试2;then命令序列2
else命令序列n
fi
2.case判断结构

语法结构:

case 变量 in
模式1)命令序列1 ;;
模式2)命令序列2 ;;.. ..
*)默认命令序列
esac

六、循环结构

1.for循环结构

语法结构:

for 变量名 in 值1 值2 值3...
do命令序列
done

读取文件批量测试主机存活状态的脚本

#vim ping.sh
#!/bin/bash
for i in host.txt
doping -c $i &> /dev/nullif [ $? -eq 0 ];thenecho "$i主机网络正常"elseecho "$i主机网络异常"
fi
done
2.while循环结构

语法结构:

while 条件测试
do命令序列
done

猜数字脚本

# vim run.sh 
#!/bin/bash
num=$[RANDOM%10+1]
while :
doread -p "我有一个1-10的数字,你猜是啥:" caiif [ $cai -eq $num ];thenecho "猜对了"exit                  #添加exit,猜对了之后退出脚本elif [ $cai -gt $num ];thenecho "猜大了"elseecho "猜小了"fi
done
3.中断及退出

exit结束循环以及整个脚本

break可以结束整个循环

continue结束本次循环,进入下一次循环

七、字符串处理

1.字符串截取

${变量名:起始位置: 长度}

生成一个8位数随机密码的脚本

# vim password.sh
#!/bin/bash
x=abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789  
pass=""        #使用变量pass,值为空
for i in {1..8}
dotmp=${x:$[RANDOM%62]:1}    #得到0~61随机值存在变量tmp中pass+=$tmp     #将随机得到的字符赋值给变量pass  
done
echo $pass      #输出8位长度随机字符串
2.字符串替换

只替换第一个:${变量名/old/new}

替换全部:${变量名//old/new}

掐头去尾:

从左往右,最短匹配删除:${变量名#*关键词}

从左往右,最长匹配删除:${变量名##*关键词}

从右往左,最短匹配删除:${变量名%关键词*}

从右往左,最长匹配删除:${变量名%%关键词*}

3.字符串初值处理

${var:-初值}判断变量是否存在,决定变量的初始值。

读取用户文件批量创建帐号脚本

#vim useradd.sh
#!/bin/bash
for i in name.txt
douseradd $iecho ${pass:-123456} | passwd --stdin $i #设置默认密码
done
http://www.xdnf.cn/news/19804.html

相关文章:

  • C# 原型模式(C#中的克隆)
  • “转”若惊鸿,电磁“通”——耐达讯自动化RS485转Profinet点亮能源新章
  • 【NestJS】HTTP 接口传参的 5 种方式(含前端调用与后端接收)
  • 【卷积神经网络】卷积神经网络的三大核心优势:稀疏交互、参数共享与等变表示
  • C++之基于正倒排索引的Boost搜索引擎项目介绍
  • 如何解决pip安装报错ModuleNotFoundError: No module named ‘black’问题
  • 【提示词】...(后续单元)在Prompt 的作用
  • 【linux仓库】万物至简的设计典范:如何用‘文件’这一个概念操纵整个Linux世界?
  • 在Docker中安装MySQL时3306端口占用问题
  • 论文学习30:LViT: Language Meets Vision Transformerin Medical Image Segmentation
  • 使用云手机进行游戏搬砖划算吗?
  • 国内真实的交换机、路由器和分组情况
  • 【保姆级喂饭教程】把chrome谷歌浏览器中的插件导出为CRX安装包
  • LeetCode 925.长按键入
  • 数据结构:希尔排序 (Shell Sort)
  • 【51单片机】【protues仿真】基于51单片机呼叫系统
  • 基于Force-closure评估的抓取计算流程
  • 生成知识图谱与技能树的工具指南:PlantUML、Mermaid 和 D3.js
  • 【AI报表】JimuReport 积木报表 v2.1.3 版本发布,免费可视化报表和大屏
  • 【leetcode】222. 完全二叉树的节点个数
  • Altium Designer中的Net-Tie:解决多网络合并与电气隔离的利器
  • CPTS-Vintage 票据,基于资源的约束委派 (RBCD),DPAPI密钥
  • 自制扫地机器人(二) Arduino 机器人避障设计——东方仙盟
  • Veo Videos Generation API 对接说明
  • 鸿蒙NEXT表单选择组件详解:Radio与Checkbox的使用指南
  • 开源 C++ QT Widget 开发(十)IPC进程间通信--共享内存
  • 零跑汽车8月交付57066台,同比增长超88%
  • amd cpu是x86架构吗
  • 【Audio】静音或振动模式下重复来电响铃
  • stdexcept介绍与使用指南