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

文章目录

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

简单Shell脚本编写

Shell脚本概念

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

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

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

1. 简单脚本编写

文件内容如下:

image-20230903114629343

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

方式一

chmod +x 脚本文件

image-20230903114742333

方式二

bash 脚本文件

image-20230903114659648

2. Shell脚本参数

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

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

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

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

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

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

image-20230903120223123

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

执行结果:

image-20230903120259036

注意

  • 双引号会解释变量

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

2.1 Shell脚本参数判断

2.1.1 文件测试语句

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

判读是否为目录

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

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

image-20230903123048335

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

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

image-20230903123346602

判断是否为文件

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

image-20230903123516341

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

2.1.2 逻辑测试语句

逻辑运算符:

  • &&
  • ||

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

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

image-20230903124043040

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

  • && 必须保证两边都为真,条件才会成立,只要有一个为假条件都不会成立。
  • 只有当左侧命令执行成功时,右侧的命令才会被执行。
[ -f /etc/passwd ] && echo  "/etc/passwd是一个文件"
[ -d wuhu ] && echo  "wuhu是一个目录"

image-20230903124711636

[ $USER = root ] && echo  "该用户是超级管理员用户"

image-20230903125212876

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

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

image-20230903125749282

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

[ ! $USER = root ] && echo "user" || echo "superuser"

image-20230903131030219

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

image-20230903131230506

2.1.3 整数值测试语句

整数的比较运输符

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

image-20230903134238723

free:查看内存

image-20230903134650248

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

free -m | grep Mem | awk '{print $4}'

image-20230903134734422

定义变量

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

image-20230903135523368

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

[ $Freemem -gt 1024 ] && echo "内存不足"
[ $Freemem -lt 1024 ] && echo "内存不足"

image-20230903135912372

2.1.4 字符串比较语句

字符串比较:

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

image-20230903140444779

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

[ $LANG = zh_CN.UTF-8 ] && echo "支持中文" || echo "不支持中文"

image-20230903141125055

3. Shell流程控制语句

流程控制语句

  • if
  • then
  • else
  • fi

3.1 if 条件测试语句

3.1.1 if…

基本格式如下:

if 条件测试语句		
then 命令序列
fi  结束if语句

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

#!/bin/bash
DIR="/home/test"
if [ ! -e $DIR ]
thenmkdir -p $DIR
fi

image-20230903142903331

执行结果

image-20230903143054035

3.1.2 if…else…

基本格式如下:

if 条件测试语句		
then 命令序列
else 命令序列
fi  结束if语句

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

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

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

image-20230903144743570

执行结果

image-20230903144820330

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

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

说明

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

image-20230903150021885

执行效果

image-20230903150119546

3.1.3 if…elif…else

基本格式如下:

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

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

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

说明:

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

image-20230903152258328

执行效果如下

image-20230903152359934

4. Shell脚本循环

4.1 for循环

基本格式:

for 变量名 in 取值列表
do命令序列
done

4.1.1 批量添加用户

创建一个用户名的txt文件

image-20230903153430251

编写Shell脚本

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

说明

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

image-20230903154931261

执行结果如下:

image-20230903155507018

创建前

image-20230903155024371

创建后image-20230903155524208

4.1.2 批量删除用户

编写Shell脚本

#!/bin/bash
for USERNAME in `cat user.txt`
doid $USERNAME &> /dev/nullif [ $? -eq 0 ]thenuserdel -r $USERNAME &>/dev/nullecho "$USERNAME用户已删除"elseecho "$USERNAME用户不存在!"fi
done

image-20230903161734398

执行结果

image-20230903161831687

4.1.3 批量ping IP 地址

创建一个IP地址的txt文件

image-20230903162332275

编写Shell脚本

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

说明

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

image-20230903162909854

执行效果如下:

image-20230903163034465

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

方式一

#!/bin/bash
read -p "请输入网络位:" NETWORK
for ((IP=1;IP<=100;IP++))
doping -c 3 -i 0.2 -W 3 $NETWORK.$IP &> /dev/nullif [ $? -eq 0 ]thenecho "$NETWORK.$IP该IP可以ping通"elseecho "$NETWORK.$IP该IP无法ping通!!!!!!!"fi
done

执行结果:

image-20230903165538490

方式二

#!/bin/bash
read -p "请输入网络位:" NETWORK
for IP in `seq 1 254`
doping -c 3 -i 0.2 -W 3 $NETWORK.$IP &> /dev/nullif [ $? -eq 0 ]thenecho "$NETWORK.$IP该IP可以ping通"elseecho "$NETWORK.$IP该IP无法ping通!!!!!!!"fi
done

说明:

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

执行结果:

image-20230903165524898

4.2 while循环

基本格式如下:

while 条件
do命令序列
done

例如:猜测商品价格

编写Shell脚本

#!/bin/bash
echo "该商品价格在0~1000之间,输入价格来猜一猜"
TIMES=0
PRICE=$(expr $RANDOM % 1000 )
while true
doread -p "请输入价格:" INTlet TIMES++if [ $INT -eq $PRICE ]then    echo "恭喜您猜对了该商品的及格,价格为$INT"echo "您猜了$TIMES次"exitelif [ $INT -gt $PRICE ];thenecho "您所输入的价格高了"elseecho "您所输入的价格低了"fi      
done

说明

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

image-20230903171930137

执行结果

image-20230903172221018

4.3 case条件测试语句

基本格式如下:

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

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

编写Shell脚本

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

image-20230903173802938

执行效果如下:

image-20230903173832062

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/65602.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

汽车自适应巡航系统控制策略研究

目 录 第一章 绪论 .............................................................................................................................. 1 1.1 研究背景及意义 ..........................................................................................…

文件夹中lib,dll含义

.dll文件是动态链接库&#xff08;Dynamic Link Library&#xff09;的缩写&#xff0c;它包含了一组可执行的函数和数据&#xff0c;供程序调用。它可以被多个应用程序共享和重用&#xff0c;减少了代码的冗余。通过动态链接库&#xff0c;可以实现代码的模块化和提高代码的复…

百万级并发IM即时消息系统(4)用户基本CRUD

前置&#xff1a; 代码层次还是由低到高&#xff1a;model层数据库操作->service层封装->路由层调用业务 手把手详细教你如何使用go-swagger文档 - 掘金 (juejin.cn) golang swagger注解说明_go swagger 注释_mctlilac的博客-CSDN博客 Gin篇&#xff1a;gorm 使用 - …

ELK安装、部署、调试(五)filebeat的安装与配置

1.介绍 logstash 也可以收集日志&#xff0c;但是数据量大时太消耗系统新能。而filebeat是轻量级的&#xff0c;占用系统资源极少。 Filebeat 由两个主要组件组成&#xff1a;harvester 和 prospector。 采集器 harvester 的主要职责是读取单个文件的内容。读取每个文件&…

编译链接实战(14)符号重定位与重定位表

文章目录 1、什么是符号重定位2、重定位表1、什么是符号重定位 符号重定位的存在是为了解决程序中的符号引用问题。当一个可执行文件或共享库被编译时,其中可能会引用其他对象文件或共享库中定义的函数、变量或其他符号。这些引用通常以符号的名称表示,而不是实际的内存地址…

机器学习技术(六)——有监督学习算法之线性回归算法实操

机器学习技术&#xff08;五&#xff09;——有监督学习之线性回归算法实操 引言&#xff1a; 机器学习监督算法是一种基于已有标记数据的学习方法&#xff0c;通过对已知输入和输出数据的学习&#xff0c;建立一个模型来预测新的输入数据的输出。这种算法模仿人类的学习过程&a…

安防监控/视频汇聚平台EasyCVR调用rtsp地址返回的IP不正确是什么原因?

安防监控/云存储/磁盘阵列存储/视频汇聚平台EasyCVR可拓展性强、视频能力灵活、部署轻快&#xff0c;可支持的主流标准协议有GB28181、RTSP/Onvif、RTMP等&#xff0c;以及厂家私有协议与SDK接入&#xff0c;包括海康Ehome、海大宇等设备的SDK等&#xff0c;能对外分发RTSP、RT…

Web 应用开发 - 实训一 网页开发

Web应用开发 实训一 网页开发 一、预习&#xff1a; 1、阅读&#xff1a;教材P1-P39 2、要掌握知识要点&#xff1a;表单标记、超链接标记、CSS的引用方式、CSS选择器、DOM、JavaScript的引入&#xff08;内嵌式、外链式&#xff09;、JavaScript的使用&#xff08;事件处理…

服务器允许ssh登录root

用vim打开/etc/ssh/sshd_config sudo vim /etc/ssh/sshd_config将sshd_config中的PermitRootLogin属性改为yes ... PermitRootLogin yes ...重启sshd服务 sudo service sshd restart

docker 笔记2 Docker镜像和数据卷

参考&#xff1a; 1.镜像是什么&#xff1f;&#xff08;面试题&#xff09; 是一种轻量级、可执行的独立软件包&#xff0c;它包含运行某个软件所需的所有内容&#xff0c;我们把应用程序和配置依赖打包好形成一个可交付的运行环境(包括代码、运行时需要的库、环境变量和配置文…

微信小程序-生成canvas图片并保存到手机相册

wxml页面 <button class"rightbtn bottomBtnCss" catch:tap"canvasImg"><image src{{imgUrl}}/images/mine/jspj-icon.png class"restNumImg"></image><text class"btnText">生成图片</text></but…

算法笔记——路径问题

在引入介绍如何写一个算法的时候&#xff0c;我们先引入一个题作为例子 1137. 第 N 个泰波那契数 - 力扣&#xff08;LeetCode&#xff09; 作为刚开始学习算法的我们&#xff0c;看到这个题目的时候&#xff0c;应该想好以下的问题&#xff1a; 1.状态表示 我们要用什么来表…

Windows7安装SSH客户端的解决方案

大家好,我是爱编程的喵喵。双985硕士毕业,现担任全栈工程师一职,热衷于将数据思维应用到工作与生活中。从事机器学习以及相关的前后端开发工作。曾在阿里云、科大讯飞、CCF等比赛获得多次Top名次。现为CSDN博客专家、人工智能领域优质创作者。喜欢通过博客创作的方式对所学的…

SQL sever中库管理

目录 一、创建数据库 1.1库界面方式 1.2SQL命令方式 二、修改数据库 2.1库界面方式 2.2SQL命令方式 三、删除数据库 3.1库界面方式 3.2SQL命令方式 四、附加和分离数据库 4.1附加和分离数据库概述 4.2作用 4.3附加和分离数据库方法 4.4示例 一、创建数据库 1.1库…

第 3 章 栈和队列 (循环队列)

1. 背景说明 和顺序栈相类似&#xff0c;在队列的顺序存储结构中&#xff0c;除了用一组地址连续的存储单元依次存放从队列头到队列尾的元素之外&#xff0c; 尚需附设两个指针 front 和 rear 分别指示队列头元素及队列尾元素的位置。约定&#xff1a;初始化建空队列时&#x…

力扣:81. 搜索旋转排序数组 II(Python3)

题目&#xff1a; 已知存在一个按非降序排列的整数数组 nums &#xff0c;数组中的值不必互不相同。 在传递给函数之前&#xff0c;nums 在预先未知的某个下标 k&#xff08;0 < k < nums.length&#xff09;上进行了 旋转 &#xff0c;使数组变为 [nums[k], nums[k1], .…

XmlDocument.SelectNodes 不起作用

今天采用Xpath读取Xml节点&#xff0c;怎么都读不出。 问题分析&#xff1a; 错误代码如下&#xff1a; XmlDocument xmlD new XmlDocument();xmlD.PreserveWhitespace true;xmlD.LoadXml(xStr);xmlD.SelectNodes("job-scheduling-data/schedule/job");经排查 do…

Python学习笔记——从面试题出发学习Python

Python学习笔记——从面试题出发学习Python Python学习笔记——从面试题出发学习Python1. 可变数据类型与不可变数据类型&#xff0c;深拷贝与浅拷贝&#xff0c;函数参数的传递机制1.1 变量与对象1.2 可变数据类型与不可变数据类型1.3 深拷贝与浅拷贝1.4 函数参数的传递机制1.…

element-plus的周选择器 一周从周一开始

1、代码 1&#xff09;、template中 <el-date-picker v-model"value1" type"week" format"[Week] ww" placeholder"巡访周" change"change"value-format"YYYY-MM-DD" /> 2&#xff09;、方法中 import…

Matlab(画图初阶)

目录 1.plot()函数 2. hold(添加新绘图是否保留旧绘图) 3. Plot Style 3.1 线型 3.2 标记 3.3 颜色 ​编辑 4. legend() 5.X 、Y and Title&#xff1f; 6. Text()和annotation() 7.line(创建基本线条) 7.1 基本语法 7.2 指定线条属性 7.3 更改线条属性 8.图像属性 8.1 …