Shell脚本入门:从零到精通

发布于:2025-09-03 ⋅ 阅读:(15) ⋅ 点赞:(0)

一、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
do
    ping -c $i &> /dev/null
    if [ $? -eq 0 ];then
        echo "$i主机网络正常"
    else
        echo "$i主机网络异常"
fi
done
2.while循环结构

语法结构:

while 条件测试
do
    命令序列
done

猜数字脚本

# 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位数随机密码的脚本

# 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:-初值}判断变量是否存在,决定变量的初始值。

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

#vim useradd.sh
#!/bin/bash
for i in name.txt
do
    useradd $i
    echo ${pass:-123456} | passwd --stdin $i #设置默认密码
done

网站公告

今日签到

点亮在社区的每一天
去签到