Shell脚本入门:从零到精通

一、Shell脚本

1.什么是Shell?

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

2.什么是Shell脚本?

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

3.简单Shell脚本设计

本机快速搭建Yum仓库

bash 复制代码
#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服务

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

二、Shell变量

1.变量的设置和取消

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

定义/赋值变量

bash 复制代码
变量名=变量值
例 X=10

查看变量

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

取消变量

bash 复制代码
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)三种引号对赋值的影响 双引号可以界定一个完整的字符串。 ```bash 变量名="值1 值2 ..." 例:X="a a a" ``` 单引号可以界定一个完整的字符串,并且可以实现屏蔽特殊符号的功能。 ```bash echo '$X' ``` 反撇号或$(),可以将命令执行结果作为字符串存储。 ```bash 变量名=`执行命令` 变量名=$(执行命令) 例:a=$(date) ``` ###### (2)read标准输入取值 read从键盘读入变量值完成赋值,ssty -echo将回显功能关闭,ssty echo将回显功能恢复。 ```bash read -p "提示信息" 变量名 ``` ###### (3)变量的作用范围 局部变量:定义的变量默认只在当前Shell环境下有效,无法在子Shell环境中使用。 全局变量:能在当前Shell及子Shell环境中均有效,使用export可将局部变量声明为全局变量。 #### 三、数值运算 ##### 1.整数运算 ###### (1)$(())或$\[\]表达式 引用变量可省略$符号,计算结果替换表达式本身。 ```bash echo $[1+1] echo $[1*1] echo $[3-1] echo $((10%3)) echo $((10/2)) ``` ###### (2)变量的自增自减 let命令可以直接对变量值做运算再保存新的值。 ```bash let i++ let i-- let += 1 let -=1 let i*=2 let i/=2 let i%=2 ``` ##### 2.小数运算 将需要运算的表达式通过管道操作交给bc运算。注意,小数位的长度可采用scale=N限制。 ```bash echo "scale=2;$i * 10" | bc #多表达式 echo "$A <= $B" | bc #小数比较,返回结果为1则表达式成立,否则返回结果为0 ``` #### 四、条件测试 使用test 表达式 或者 \[ 表达式 \]可以进行条件测试,中间空格不能省略,条件测试本身不显示任何信息,可以在测试后查看$?的值来判断。 ##### 1.字符串比较 ###### (1)判断变量是否为空 \[ 操作符 字符串\] -z 字符串的值为空 -n 字符串的值不为空(相当于!-n) ```bash x=10 [ -z "$x" ] #判断x是为空 echo $? #查看上一次代码执行结果 [ -n "$x" ] #判断x非空 echo $? #查看结果 ``` ###### (2)判断字符串是否相等 \[ 字符串1 操作符 字符串2 \] == 两个字符串相同 != 两个字串不相同 ```bash a=test b=test [ "$a" == "$b" ] && echo Y || echo N #仅当判断结果正确时,执行echo Y,否则执行echo N b=text [ "$a" != "$b" ] && echo Y || echo N ``` ##### 2.整数值比较 参与比较的必须是整数,可以调用变量。 ```bash [ 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 #不相等 ``` 监控主机登录用户数量的脚本 ```bash #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判断对象是否存在,无论是目录还是文件 ```bash [ -e "/etc" ] && echo Y || echo N ``` -d判断对象是否为目录 ```bash [ -d "/etc" ] && echo Y || echo N ``` -f判断对象是否为文件 ```bash [ -f "/etc" ] && echo Y || echo N ``` -r判断对象是否可读 ```bash [ -r "/etc/hosts" ] && echo Y || echo N ``` -w判断对象是否可写 ```bash [ -w "/etc/hosts" ] && echo Y || echo N ``` -x判断对象是否具有x权限 ```bash [ -x "/etc/hosts" ] && echo Y || echo N ``` #### 五、判断结构 ##### 1.if选择结构 if单分支的语法组成: ```bash if 测试条件;then 命令序列 fi ``` if双分支的语法组成: ```bash if 条件测试;then 命令序列1 else 命令序列2 fi ``` if多分支的语法组成: ```bash if 条件测试1;then 命令序列1 elif 条件测试2;then 命令序列2 else 命令序列n fi ``` ##### 2.case判断结构 语法结构: ```bash case 变量 in 模式1) 命令序列1 ;; 模式2) 命令序列2 ;; .. .. *) 默认命令序列 esac ``` #### 六、循环结构 ##### 1.for循环结构 语法结构: ```bash for 变量名 in 值1 值2 值3... do 命令序列 done ``` 读取文件批量测试主机存活状态的脚本 ```bash #vim ping.sh #!/bin/bash for i in host.txt do ping -c $i &> /dev/null if [ $? -eq 0 ];then echo "$i主机网络正常" else echo "$i主机网络异常" fi done ``` ##### 2.while循环结构 语法结构: ```bash while 条件测试 do 命令序列 done ``` 猜数字脚本 ```bash # vim run.sh #!/bin/bash num=$[RANDOM%10+1] while : do read -p "我有一个1-10的数字,你猜是啥:" cai if [ $cai -eq $num ];then echo "猜对了" exit #添加exit,猜对了之后退出脚本 elif [ $cai -gt $num ];then echo "猜大了" else echo "猜小了" fi done ``` ##### 3.中断及退出 exit结束循环以及整个脚本 break可以结束整个循环 continue结束本次循环,进入下一次循环 #### 七、字符串处理 ##### 1.字符串截取 ${变量名:起始位置: 长度} 生成一个8位数随机密码的脚本 ```bash # vim password.sh #!/bin/bash x=abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 pass="" #使用变量pass,值为空 for i in {1..8} do tmp=${x:$[RANDOM%62]:1} #得到0~61随机值存在变量tmp中 pass+=$tmp #将随机得到的字符赋值给变量pass done echo $pass #输出8位长度随机字符串 ``` ##### 2.字符串替换 只替换第一个:${变量名/old/new} 替换全部:${变量名//old/new} 掐头去尾: 从左往右,最短匹配删除:${变量名#\*关键词} 从左往右,最长匹配删除:${变量名##\*关键词} 从右往左,最短匹配删除:${变量名%关键词\*} 从右往左,最长匹配删除:${变量名%%关键词\*} ##### 3.字符串初值处理 ${var:-初值}判断变量是否存在,决定变量的初始值。 读取用户文件批量创建帐号脚本 ```bash #vim useradd.sh #!/bin/bash for i in name.txt do useradd $i echo ${pass:-123456} | passwd --stdin $i #设置默认密码 done ```

相关推荐
dingdingfish18 小时前
GNU Parallel 学习 - 第1章:How to read this book
bash·shell·gnu·parallel
似霰4 天前
Linux Shell 脚本编程——核心基础语法
linux·shell
似霰4 天前
Linux Shell 脚本编程——脚本自动化基础
linux·自动化·shell
偷学技术的梁胖胖yo5 天前
Shell脚本中连接数据库查询数据报错 “No such file or directory“以及函数传参数组
linux·mysql·shell
纵有疾風起14 天前
【Linux 系统开发】基础开发工具详解:软件包管理器、编辑器。编译器开发实战
linux·服务器·开发语言·经验分享·bash·shell
gis分享者16 天前
Shell 脚本中如何使用 here document 实现多行文本输入? (中等)
shell·脚本·document·多行·文本输入·here
柏木乃一16 天前
基础IO(上)
linux·服务器·c语言·c++·shell
angushine17 天前
CPU脚本并远程部署
shell
赵民勇21 天前
Linux/Unix中install命令全面用法解析
linux·shell
gis分享者22 天前
Shell 脚本中如何使用 trap 命令捕捉和处理信号(中等)
shell·脚本·信号·处理·trap·捕捉