一篇文章教会你如何编写一个简单的Shell脚本

文章目录

  • 简单Shell脚本编写
    • [1. 简单脚本编写](#1. 简单脚本编写)
    • [2. Shell脚本参数](#2. Shell脚本参数)
      • [2.1 Shell脚本参数判断](#2.1 Shell脚本参数判断)
        • [2.1.1 文件测试语句](#2.1.1 文件测试语句)
        • [2.1.2 逻辑测试语句](#2.1.2 逻辑测试语句)
        • [2.1.3 整数值测试语句](#2.1.3 整数值测试语句)
        • [2.1.4 字符串比较语句](#2.1.4 字符串比较语句)
    • [3. Shell流程控制语句](#3. Shell流程控制语句)
      • [3.1 if 条件测试语句](#3.1 if 条件测试语句)
        • [3.1.1 if...](#3.1.1 if...)
        • [3.1.2 if...else...](#3.1.2 if...else...)
        • [3.1.3 if...elif...else](#3.1.3 if...elif...else)
    • [4. Shell脚本循环](#4. Shell脚本循环)
      • [4.1 for循环](#4.1 for循环)
        • [4.1.1 批量添加用户](#4.1.1 批量添加用户)
        • [4.1.2 批量删除用户](#4.1.2 批量删除用户)
        • [4.1.3 批量ping IP 地址](#4.1.3 批量ping IP 地址)
        • [4.1.4 检测同一局域网,多台主机存活情况](#4.1.4 检测同一局域网,多台主机存活情况)
      • [4.2 while循环](#4.2 while循环)
      • [4.3 case条件测试语句](#4.3 case条件测试语句)

简单Shell脚本编写

Shell脚本概念

Shell 脚本是一种用于自动化执行一系列命令和操作的脚本文件。它使用的是 Shell 解释器(如 Bash、Korn Shell、Zsh 等)来解释和执行其中的命令。Shell 脚本通常用于编写简单的任务和工作流程,可以帮助我们进行系统管理、批量处理、自动化部署等任务。

以.sh后缀名结尾的文件来表示该文件是一个Shell脚本。

Shell脚本就是将命令写入文本中,文本可以被执行。

1. 简单脚本编写

文件内容如下:

编写完脚本后,赋权文件的执行权限

方式一

sh 复制代码
chmod +x 脚本文件

方式二

sh 复制代码
bash 脚本文件

2. Shell脚本参数

$0:表示当前脚本的名称。

$*:表示脚本的所有参数。

$#:表示脚本的参数的个数。

$n:表示脚本的第n个参数,n=1,2,3...

$? :程序执行完后的结果,返回值0表示执行成功。

sh 复制代码
#!/bin/bash
echo "当前脚本名称$0"
echo "总共有$#个参数,分别是$*。"
echo "第一个参数为$1,第三个参数为$3"

在执行该Shell脚本文件的时候在后面添加三个参数分别是wuhu1,wuhu2,wuhu3。

执行结果:

注意

  • 双引号会解释变量

  • 单引号会把变量当成字符串表示

2.1 Shell脚本参数判断

2.1.1 文件测试语句

  • -d:测试文件是否为目录类型,是目录返回0,不是目录返回非0值。
  • -e:测试文件是否存在。
  • -f:判断是否为一般文件。
  • -r:判断当前用户对该文件是否有读取权限。
  • -w:判断当前用户对该文件是否有写入权限。
  • -x:判断当前用户对该文件是否有执行权限。

判读是否为目录

sh 复制代码
[ -d /etc/passwd ]
echo $?				# $?返回上一次执行命令的结果

说明:这里的[]中输入的内容前后需要加空格

返回值为1,表示/etc/passwd不是目录。

判断当前目录下的wuhu是否为目录

判断是否为文件

[ -f /etc/passwd ]
echo $?				# $?返回上一次执行命令的结果

返回值为0,表示/etc/passwd是文件。

2.1.2 逻辑测试语句

逻辑运算符:

  • &&
  • ||

问题:上面所输入命令十分的繁琐,是否可以使用一条命令来完成上面的操作?

注意:这里是不能使用管道符的,使用管道符发现两次的输出值是不一样的。

可以使用**&&**符号

  • && 必须保证两边都为真,条件才会成立,只要有一个为假条件都不会成立。
  • 只有当左侧命令执行成功时,右侧的命令才会被执行。
sh 复制代码
[ -f /etc/passwd ] && echo  "/etc/passwd是一个文件"
[ -d wuhu ] && echo  "wuhu是一个目录"
sh 复制代码
[ $USER = root ] && echo  "该用户是超级管理员用户"

还可以使用**|| **符号

  • || 两边有一个为真就为真,两边都为真也为真,两边为假才为假。
  • 如果左侧命令执行成功(返回值为零),则右侧的命令将不会被执行。
sh 复制代码
[ $USER = root ] || echo  "该用户是超级管理员用户"		# 表示当前用户不是root输出对应的语句

[ ! $USER = root ] || echo  "该用户是超级管理员用户"	# 表示当前用户是root输出对应的语句

例如:要求普通用户输出user,管理员用户输出superuser

sh 复制代码
[ ! $USER = root ] && echo "user" || echo "superuser"

切换回普通用户,执行该命令

2.1.3 整数值测试语句

整数的比较运输符

  • -eq:是否等于
  • -ne:是否不等于
  • -gt:是否大于
  • -lt:是否小于
  • -le:是否等于或小于
  • -ge:是否等于或大于
sh 复制代码
[ 9 -eq 8 ]
echo $?

[ 9 -ne 8 ]
echo $?

free:查看内存

现在需要输出free中的Mem这一行

sh 复制代码
free -m | grep Mem | awk '{print $4}'

定义变量

sh 复制代码
Freemem=`free -m | grep Mem | awk '{print $4}'`
echo $Freemem			# 输出变量

例如:如果这个值小于1024的时候,会输出内容不足的提示信息。

sh 复制代码
[ $Freemem -gt 1024 ] && echo "内存不足"
[ $Freemem -lt 1024 ] && echo "内存不足"

2.1.4 字符串比较语句

字符串比较:

  • =:比较字符串内容是否相同。
  • !=:比较字符串内容是否不同。
  • -z:判断字符串内容是否为空,如果为空返回0表示真,如果不为空返回1。
sh 复制代码
[ -z $String ]
echo $?			# 返回结果为0,因为没有定义过这个变量

[ -z $USER ]
echo $?			# 返回结果为1,因为当前用户不为空

判断当前系统是否支持中文。

sh 复制代码
[ $LANG = zh_CN.UTF-8 ] && echo "支持中文" || echo "不支持中文"

3. Shell流程控制语句

流程控制语句

  • if
  • then
  • else
  • fi

3.1 if 条件测试语句

3.1.1 if...

基本格式如下:

sh 复制代码
if 条件测试语句		
then 
	命令序列
fi  结束if语句

例如:判断home目录下是否存在test目录,如果不存在则创建一个。

sh 复制代码
#!/bin/bash
DIR="/home/test"
if [ ! -e $DIR ]
then
        mkdir -p $DIR
fi

执行结果

3.1.2 if...else...

基本格式如下:

sh 复制代码
if 条件测试语句		
then 
	命令序列
else 
	命令序列
fi  结束if语句

例如:判断给定的IP是否正常

sh 复制代码
#!/bin/bash
ping -c 3 -i 0.2 -W 3 $1 &>/dev/null
if [ $? -eq 0 ]
then
        echo "$1该IP是正常的"
else 
        echo "$1该IP无法ping通" 
fi 

说明:&>/dev/null在 Linux/Unix 系统中,"/dev/null" 是一个空设备文件,它可以用于丢弃不需要的输出,相当于一个黑洞。

执行结果

然后就可以完善一下脚本内容

shell 复制代码
#!/bin/bash
if [ -z $1 ]
then
        echo "作者:小薛"
        echo "该命令检测服务器IP是否正常"
        echo "直接在命令后面加参数IP就可以执行"
else
        ping -c 3 -i 0.2 -W 3 $1 &>/dev/null
        if [ $? -eq 0 ]
        then
                echo "$1该IP是正常的"
        else
                echo "$1该IP无法ping通" 
        fi
fi

说明

  • "-c 3" 选项表示发送 3 个 ICMP 请求消息,并等待每个请求的响应。
  • "-i 0.2" 选项表示设置每个 ICMP 请求的时间间隔为 0.2 秒(即每 200 毫秒发送一个请求)。
  • "-W 3" 选项表示设置等待响应的超时时间为 3 秒。

执行效果

3.1.3 if...elif...else

基本格式如下:

sh 复制代码
if 条件测试语句1	
then 
	命令序列1
elif 条件测试语句2
then 
	命令序列2
else 
	命令序列3
fi  结束if语句

例如:判断学员考试分数如何

sh 复制代码
#!/bin/bash
read -p "请输入分数(1-100):" fenshu
if [ $fenshu -ge 85 ] && [ $fenshu -le 100 ];then
        echo "该学生成绩为优秀"
elif [ $fenshu -ge 70 ] && [ $fenshu -le 84 ];then
        echo "该学生成绩为合格"
else
        echo "该学生成绩为不合格"               
fi

说明:

  • "-p" 选项用于在用户输入之前显示一个提示信息。
  • "read" 是一个 Bash 内置命令,用于从标准输入中读取用户输入并将其赋值给一个变量。
  • "fenshu" 是用于存储用户输入值的变量名。

执行效果如下

4. Shell脚本循环

4.1 for循环

基本格式:

sh 复制代码
for 变量名 in 取值列表
do
	命令序列
done

4.1.1 批量添加用户

创建一个用户名的txt文件

编写Shell脚本

sh 复制代码
#!/bin/bash
read -p "请输入密码:" PASSWORD
for USERNAME in `cat user.txt`
do      
        id $USERNAME &> /dev/null
        if [ $? -eq 0 ]
        then    
                echo "$USERNAME用户已存在!"
        else    
                useradd $USERNAME &> /dev/null
                echo "$PASSWORD" | passwd --stdin $USERNAME &> /dev/null
                echo "$USERNAME用户创建成功"
        fi      
done

说明

  • --stdin:选项告诉passwd命令从标准输入(stdin)读取密码,而不是要求用户手动输入密码。

执行结果如下:

创建前

创建后

4.1.2 批量删除用户

编写Shell脚本

sh 复制代码
#!/bin/bash
for USERNAME in `cat user.txt`
do
        id $USERNAME &> /dev/null
        if [ $? -eq 0 ]
        then
                userdel -r $USERNAME &>/dev/null
                echo "$USERNAME用户已删除"
        else
                echo "$USERNAME用户不存在!"
        fi
done

执行结果

4.1.3 批量ping IP 地址

创建一个IP地址的txt文件

编写Shell脚本

sh 复制代码
#!/bin/bash
HOSTLIST=$(cat /root/iplist.txt)
for IP in $HOSTLIST
do
        ping -c 3 -i 0.2 -W 3 $IP &>/dev/null
        if [ $? -eq 0 ]
        then    
                echo "$IP该IP是正常的"
        else    
                echo "$IP该IP无法ping通"
        fi      
done

说明

  • "$()" 是 Bash 中的命令替换语法,它表示将命令的输出结果作为一个整体嵌入到命令行中。

执行效果如下:

4.1.4 检测同一局域网,多台主机存活情况

方式一

sh 复制代码
#!/bin/bash
read -p "请输入网络位:" NETWORK
for ((IP=1;IP<=100;IP++))
do
        ping -c 3 -i 0.2 -W 3 $NETWORK.$IP &> /dev/null
        if [ $? -eq 0 ]
        then
                echo "$NETWORK.$IP该IP可以ping通"

        else
                echo "$NETWORK.$IP该IP无法ping通!!!!!!!"
        fi
done

执行结果:

方式二

sh 复制代码
#!/bin/bash
read -p "请输入网络位:" NETWORK
for IP in `seq 1 254`
do
        ping -c 3 -i 0.2 -W 3 $NETWORK.$IP &> /dev/null
        if [ $? -eq 0 ]
        then
                echo "$NETWORK.$IP该IP可以ping通"

        else
                echo "$NETWORK.$IP该IP无法ping通!!!!!!!"
        fi
done

说明:

  • "seq" 是一个用于生成序列的命令。
  • "1" 是序列的起始值。
  • "254" 是序列的结束值。

执行结果:

4.2 while循环

基本格式如下:

sh 复制代码
while 条件
do
	命令序列
done

例如:猜测商品价格

编写Shell脚本

sh 复制代码
#!/bin/bash
echo "该商品价格在0~1000之间,输入价格来猜一猜"
TIMES=0
PRICE=$(expr $RANDOM % 1000 )
while true
do
        read -p "请输入价格:" INT
        let TIMES++
        if [ $INT -eq $PRICE ]
        then    
                echo "恭喜您猜对了该商品的及格,价格为$INT"
                echo "您猜了$TIMES次"
                exit
        elif [ $INT -gt $PRICE ];then
                echo "您所输入的价格高了"
        else
                echo "您所输入的价格低了"
        fi      
done

说明

  • $RANDOM是linux中的内置变量,可以随机生成0-32767之间的整数数字。
  • "expr" 是一个用于执行基本数学运算或字符串操作的命令。

执行结果

4.3 case条件测试语句

基本格式如下:

sh 复制代码
case 变量值 in 
模式1
	命令序列1
模式2 
	命令序列2
....
	默认命令序列
esac

例如:判断输入的是字母,数字,还是特殊符号

编写Shell脚本

sh 复制代码
#!/bin/bash
read -p "请输入一个字符:" KEY
case "$KEY" in
        [a-z]|[A-Z])
                echo "这是字母"
                ;;
        [0-9])
                echo "这是数字"
                ;;
        *)
                echo "这是特殊符号"
esac

执行效果如下:

相关推荐
康熙38bdc1 小时前
Linux 进程优先级
linux·运维·服务器
hhzz1 小时前
Linux Shell编程快速入门以及案例(Linux一键批量启动、停止、重启Jar包Shell脚本)
android·linux·jar
只是有点小怂1 小时前
parted是 Linux 系统中用于管理磁盘分区的命令行工具
linux·运维·服务器
CyberMuse2 小时前
网络安全cybersecurity的几个新领域
网络安全
三枪一个麻辣烫2 小时前
linux基础命令
linux·运维·服务器
HEX9CF2 小时前
【CTF Web】Pikachu xss之href输出 Writeup(GET请求+反射型XSS+javascript:伪协议绕过)
开发语言·前端·javascript·安全·网络安全·ecmascript·xss
cuisidong19972 小时前
如何在 Kali Linux 上安装 Google Chrome 浏览器
linux·运维·chrome
kuber09093 小时前
APISIX 联动雷池 WAF 实现 Web 安全防护
网络安全
光通信学徒3 小时前
ubuntu图形界面右上角网络图标找回解决办法
linux·服务器·ubuntu·信息与通信·模块测试
南种北李3 小时前
Linux自动化构建工具Make/Makefile
linux·运维·自动化