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
相关推荐
吴声子夜歌8 天前
Shell编程实例——编写安全的shell脚本(二)
linux·运维·shell
吴声子夜歌9 天前
Shell编程实例——内务及管理任务(一)
linux·运维·shell
吴声子夜歌9 天前
Shell编程实例——高级脚本编程(一)
linux·运维·网络·shell
吴声子夜歌9 天前
Shell编程实例——bash的配置与自定义(二)
linux·运维·shell
吴声子夜歌10 天前
Shell编程实例——与解析相关的任务(二)
linux·运维·shell
吴声子夜歌10 天前
Shell编程实例——脚本编程的附加特性
linux·运维·shell
云计算练习生10 天前
什么是内核?操作系统内核到底管哪些事
linux·windows·操作系统·内核·shell
吴声子夜歌13 天前
Shell编程实例——bash入门
linux·运维·shell
Swizard13 天前
Linux 日志神器 journalctl 完全指南:彻底替代传统日志查看方式
shell
吴声子夜歌14 天前
Shell编程——数组
linux·运维·shell