编写交互式 Shell 脚本

在日常的系统管理和自动化任务中,使用 Shell 脚本可以为我们节省大量时间和精力。

文章将以输入 IP 为例,通过几个版本逐步完善一个案例。

原始需求

编写一个交互式的 Shell 脚本,运行时让用户可以输入IP地址,并且脚本会将输入的IP地址打印出来。

实现

首先,在命令行终端下创建一个新的文件,比如 i-demo.sh,并确保该文件具有可执行权限。

touch i-demo.sh
chmod +x i-demo.sh

版本一

shell 编程中,read 命令可以在运行时阻塞线程,并等待用户输入。因此脚本可以简单实现如下:

#!/bin/bash

read userIP

echo "You entered IP : " $userIP

以上代码中 read 命令用于提示用户输入IP地址,并将用户输入存储在变量 userIP 中。随后,echo 命令用于打印出用户输入的IP地址。

版本二

添加提示符 “Please Input IP:”,使得交互比较友好

#!/bin/bash

read -p "Please Input IP: " userIP

echo "You entered IP: $userIP"

read -p 是 Shell 脚本中用来提示用户输入的命令。它的作用是在用户输入之前,向屏幕上显示一行提示信息,让用户知道他们需要输入什么样的内容。-p 选项表示 prompt(提示),后面紧跟着要显示给用户的提示信息。

版本三

给一个默认值。

#!/bin/bash

defaultIP=127.0.0.1

read -p "Please Input IP: " userIP

if [ -z $userIP ]; then
	userIP=$defaultIP
fi

echo "You entered IP: $userIP"

其中,if [ -z $userIP ] 表示输入为空时,将 userIP 赋值为默认值 defaultIP

另一种实现:

#!/bin/bash

defaultIP=127.0.0.1

read -p "Please Input IP: " userIP

userIP=${userIP:-$defaultIP}

echo "You entered IP: $userIP"

其中 userIP=${userIP:-$defaultIP} 这行代码将会把 $userIP 的值设置为 $defaultIP 的值,当且仅当 $userIP 未被设置或者为空。这个语法可以用来提供一个默认值,以防止变量为空时的错误。

效果如下:
在这里插入图片描述
其中,第一次输出默认值。第二次输出输入的值。

版本四

在光标处展示默认值,并且支持用户直接编辑

#!/bin/bash

defaultIP=127.0.0.1

read -p "Please Input IP (default: $defaultIP): " -e -i "$defaultIP" userIP

userIP=${userIP:-$defaultIP}

echo "You entered IP: $userIP"

其中 read 命令后的 -e -i "$defaultIP" 将默认IP放置在了光标处,并支持编辑。

效果如下:
在这里插入图片描述
上图中第一次直接回车,打印了默认值。第二次直接便捷给出的默认IP,回车后打印编辑后的IP.

在这里插入图片描述

版本五

在默认值的基础上添加IP校验,并且校验不通过时,提示再次输入

#!/bin/bash

defaultIP=127.0.0.1

# IP 校验函数
function validateIP() {
    local ip=$1
    if [[ $ip =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then
        local IFS=.
        ip=($ip)
        (( ${ip[0]} <= 255 && ${ip[1]} <= 255 && ${ip[2]} <= 255 && ${ip[3]} <= 255 ))
        return $?
    else
        return 1
    fi
}

# 提示输入
read -p "Please Input IP (default is $defaultIP): "  -e -i $defaultIP userIP
userIP=${userIP:-$defaultIP}

# 校验,若不通过一直循环
while true; do
    if ! validateIP "$userIP"; then
        read -p "Invalid IP format ($userIP). Please try again: " userIP
    else
        break
    fi
done

# 打印结果
echo "You entered a valid IP: $userIP"

其中

  • local IFS=. :这行代码中的 IFS 是 Bash shell 中的一个特殊变量,它代表了“Internal Field Separator”(内部字段分隔符),用来指定在 Bash shell 中如何切割字符串。在这行代码中,将 IFS 设置为 . ,意味着告诉 Bash 在处理字符串时,以 . 作为分隔符来切割字符串。

  • ip=($ip): 这行代码使用了 Bash 中的数组赋值语法。它将名为 ip 的字符串分割成一个数组,按照内部字段分隔符(IFS)中指定的字符(在这个例子中是.)进行分割。这意味着,如果 $ip 包含了一个IP地址,那么这个命令会把IP地址中的每一部分分别存储到数组 ip 的不同元素中。
    例如,如果 $ip 的值为 192.168.1.1,那么执行 ip=($ip) 后,数组 ip 的各个元素就会分别存储为 ${ip[0]} = 192, ${ip[1]} = 168, ${ip[2]} = 1, ${ip[3]} = 1

  • (( ${ip[0]} <= 255 && ${ip[1]} <= 255 && ${ip[2]} <= 255 && ${ip[3]} <= 255 )) :这行代码使用了 Bash 中的算术表达式 ((...)),并结合了数组中的值进行了数值比较。
    在这里,${ip[0]}${ip[1]}${ip[2]}${ip[3]} 分别代表了 IP 地址中的四个部分。通过将它们与常量值 255 进行比较,并使用逻辑与运算符 && 来连接所有比较操作,可以确保每个部分都不大于 255。
    因此,整个表达式的含义是:检查 IP 地址的各个部分是否都小于等于 255。如果所有条件都成立,那么整个表达式的结果为真(非零),否则为假(零)。

  • $?: 是在Bash中用来获取上一个命令的退出状态的特殊变量。当执行一个命令后,$? 会保存该命令的退出状态或者返回值。
    通常情况下,如果命令执行成功,则$? 的值为0;如果命令执行失败,则 $? 的值为非零(通常是1)。
    在先前提到的代码中,(( ${ip[0]} <= 255 && ${ip[1]} <= 255 && ${ip[2]} <= 255 && ${ip[3]} <= 255 )) 这个条件表达式执行完毕后,它的返回值将会被保存在 $? 中。因此,可以使用 $? 来检查IP地址校验的结果,如果 $? 的值为0,则表示IP地址合法,否则表示IP地址不合法。

其效果如下
在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

linux批量查询python进程,批量关闭

我使用bash脚本启动了一个多进程的python代码&#xff0c;但是由于遗忘的问题&#xff0c;查看队列发现进程还在&#xff0c;但是我并不是使用linux的screen后台启动的&#xff0c;启动的进程丢失了&#xff0c;找不到启动这个的主进程了。我想能不能通过查询python启动命令&am…

HBuilderX插件

HBuilderX>工具插件安装 安装新插件 前往插件市场安装 1.DCloud插件市场 https://ext.dcloud.net.cn/ 2.GitHub官网 插件项目(下载zip) 本地离线包 离线安装插件 https://hx.dcloud.net.cn/Tutorial/OfflineInstall open /Applications/HBuilderX.app/Contents/HBuilderX/p…

【Linux】—— 信号的产生

本期&#xff0c;我们今天要将的是信号的第二个知识&#xff0c;即信号的产生。 目录 &#xff08;一&#xff09;通过终端按键产生信号 &#xff08;二&#xff09;调用系统函数向进程发信号 &#xff08;三&#xff09;由软件条件产生信号 &#xff08;四&#xff09;硬件…

硬件知识(2) 手机的传感器-sensor

#灵感# 看看小米在干啥 手机型号&#xff1a;Redmi Note 13 Pro&#xff0c;解读一下它宣传的手机卖点。 目录 宣传1&#xff1a;1/1.4" 大底&#xff0c;f/1.65 大光圈&#xff0c; 宣传2&#xff1a;支持 2 亿像素超清直出&#xff0c;分辨率高达 16320 x 12240 宣…

SeaTunnel Web安装 一把成

安装相关jar包&#xff0c;以及SeaTunnel 和Web 打成的包&#xff0c;可以直接使用&#xff0c;但是需要安装MySQL客户端的分享&#xff1a; 链接&#xff1a;https://pan.baidu.com/s/1qrt1RAX38SgIpNklbQJ7pA 提取码&#xff1a;0kmf 1. 环境准备 环境名称版本系统环境C…

叙永微公益开展“暖冬童梦·妙想之旅”未成年关爱活动第一天

为了丰富未成年人的寒假生活&#xff0c;让他们在轻松愉快的氛围中发挥创意、锻炼动手能力&#xff0c;同时也能得到学习的辅导。叙永县微公益协会组织大学生志愿者在叙永县新时代文明实践中心、叙永县社工总站、叙永县一品城小区、古寨社区开展为期一周的未成年关爱陪伴活动。…

使用plotly dash 画3d圆柱(Python)

plotly3D &#xff08;3d charts in Python&#xff09;可以画3维图形 在做圆柱的3D装箱项目&#xff0c;需要装箱的可视化&#xff0c;但是Mesh &#xff08;3d mesh plots in Python&#xff09;只能画三角形&#xff0c;所以需要用多个三角形拼成一个圆柱&#xff08;想做立…

四、ES集群安全策略设置 X-pack

本文主要是结合ES集群搭建时使用&#xff0c;并且适用于ES7.x以上版本 背景及安全策略方案对比 ES 7.x以下版本默认几乎没有任何安全策略&#xff0c;如果集群IP、端口被暴露&#xff0c;在可访问的情况下任何用户都可以对索引进行管理以及数据的增删改查等&#xff0c;基于此需…

国外非常好的渗透测试资源集合和十大渗透测试演练系统,系统被攻击渗透入侵后进行取证和溯源

国外非常好的渗透测试资源集合和十大渗透测试演练系统,系统被攻击渗透入侵后进行取证和溯源。 Awesome Penetration Testing A collection of awesome penetration testing resources Online Resources Penetration Testing Resources Exploit development Social Enginee…

成功解决AttributeError: ‘str‘ object has no attribute ‘get‘

成功解决AttributeError: ‘str’ object has no attribute ‘get’. &#x1f335;文章目录&#x1f335; &#x1f333;引言&#x1f333;&#x1f333;报错分析及解决方案&#x1f333;&#x1f333;字典对象的get方法&#x1f333;&#x1f333;结尾&#x1f333; &#x1…

安全测试-pikachu靶场搭建

pikachu靶场搭建 文章目录 pikachu安装步骤 pikachu pikachu是一个自带web漏洞的应用系统&#xff0c;在这里包含了常见的web安全漏洞&#xff0c;也就是练习的靶场。 练习内容包括&#xff1a; 1.暴力破解 2.XSS 3.CSRF 4.SQL注入 5.RCE 6.文件包含 7.不安全的文件下载 8.不安…

免 费 小程序商城搭建之b2b2c o2o 多商家入驻商城 直播带货商城 电子商务b2b2c o2o 多商家入驻商城 直播带货商城 电子商务

1. 涉及平台 平台管理、商家端&#xff08;PC端、手机端&#xff09;、买家平台&#xff08;H5/公众号、小程序、APP端&#xff08;IOS/Android&#xff09;、微服务平台&#xff08;业务服务&#xff09; 2. 核心架构 Spring Cloud、Spring Boot、Mybatis、Redis 3. 前端框架…

c语言学习笔记

逗号表达式 #include <stdio.h>int main(){int a 10;int b 5;int c 6;int d (a 23,b a-4,c b2);printf("%d",d); }打印结果为: 逗号表达式,从左往右依次进行,将最后一个表达式的值赋值给变量. c语言字符串相关库函数 求字符串长度strlen长度不受限制的…

web wifi配网和模式切换-esp8266和esp32

web wifi配网和模式切换-esp8266和esp32 支持模式:1:tcp client() 2:tcp server 3:http server(POST/GET) 4:http client 5:udp,6:factory,7:mqtt 配网进入方式&#xff1a; 开机&#xff0c;指示灯亮起后(需要灯闪烁3下后)&#xff0c;需在3s内&#xff08;超过3s则会正常启动…

WebGL技术开发框架

WebGL技术框架是一些提供了便捷API和工具的库&#xff0c;用于简化和加速在Web浏览器中使用WebGL进行3D图形开发。以下是一些常用的WebGL技术框架&#xff0c;希望对大家有所帮助。北京木奇移动技术有限公司&#xff0c;专业的软件外包开发公司&#xff0c;欢迎交流合作。 1.Th…

vue+ElementPlus实现中国省市区三级级联动封装

安装插件获取中国省份的所有数据 npm install element-china-area-data -S 借助ElementPlus 级联选择器 Cascader实现 <template><div><el-cascadersize"large":options"options"v-model"selectedOptions"change"handleCh…

32OLED中断系统&对射式红外计数&旋转编码计数

一.程序调试方式 二.OLED简介 stm32引脚上电后&#xff0c;如果不初始化&#xff0c;默认是浮空输入的模式&#xff0c;在这个模式下引脚不会输出电平 三. 中断系统 EXTI外部中断&#xff0c;TIM定时器&#xff0c;ADC模数转换器&#xff0c;USART串口&#xff0c;SPI通信&…

【SpringBoot3】集成Knife4j、springdoc-openapi作为接口文档

一、什么是springdoc-openapi Springdoc-openapi 是一个用于生成 OpenAPI&#xff08;之前称为 Swagger&#xff09;文档的库&#xff0c;专为 Spring Boot 应用程序设计。它可以根据你的 Spring MVC 控制器、REST 控制器和其他 Spring Bean 自动生成 OpenAPI 文档&#xff0c…

Google Chrome 中出现 ERR_SSL_KEY_USAGE_INCOMPATIBLE 错误

证书的方式发生了变化&#xff0c;出现了这个新错误&#xff0c;导致我无法浏览该网站。 可以右键属性获取位置 关闭导航器chrome并转到文件夹&#xff0c;找到Local State文件并删除 执行指令结束进程&#xff0c;重新打开浏览器即可 taskkill /im "chrome.exe"…

Unity3d实现简单的战斗

使用u3d实现一个简单的战斗demo&#xff0c;记下学到的知识点&#xff0c;以备后查。 1.判断是否点中指定物体 if (Input.GetMouseButton(0)) {Ray ray Camera.main.ScreenPointToRay(Input.mousePosition);if (Physics.Raycast(ray, out RaycastHit hit)){//坐标转换Vector…