【Linux】处理用户输入
一、基本介绍
1、如何传递参数
向shell脚本传递数据的最基本方法就是通过命令行参数。如下,这条命令会向test.sh脚本传递10和20这两个参数。
./test.sh 10 20
2、如何读取参数
bash shell会将所有的命令行参数都指派给称作位置参数(positional parameter)的特殊变量,包括shell脚本名称。
$0:对应脚本名;
$1:对应第一个命令行参数
$2:对应第二次命令参数
以此类推,直到$9
#!/bin/bash#计算阶乘
factorial=1
for (( a = 1; a <= $1; a++ ))
dofactorial=$[ $factorial * $a ]
done
echo "$1的阶乘是$factorial."
因为传入的参数之间是以空格分隔的,如果传入的参数带有空格,就需要使用引号。
#!/bin/bashecho "Hello $1, you are a good man."
exit
3、参数超过9个
如果想要传入的参数超过9个,需要在第9个位置变量后,在变量名的两侧加上花括号,如${10}。
#!/bin/bashproduct=$[ ${10} * ${11} ]
echo "第10个参数是${10}."
echo "第11个参数是${11}."
echo "product的值是$product."
exit
4、读取脚本名
如下示例会将命令名或绝对路径都当成是脚本的名称。
#!/bin/bashecho "脚本的名字是:$0"
exit
bashname命令能返回不包含命令名或绝对路径的脚本名。
#!/bin/bash#使用basename返回不包含路径的shell脚本名
shellname=$(basename $0)
echo "脚本名字是:$shellname"
exit
5、检查命令行参数是否为空
#!/bin/bashif [ -n "$1" ] #检查命令行第一个参数是否为空
thenfactorial=1for (( a = 1; a <= $1; a++ ))dofactorial=$[ $factorial * $a ]doneecho "$1的阶乘是$factorial."
elseecho "你没有提供命令行参数。"
fi
exit
二、特殊参数变量
1、$#
特殊变量$#可以获取到shell脚本运行时携带的命令行参数的数量。
#!/bin/bashif [ $# -ne 2 ]
thenecho "shell脚本$(basename $0)提供的命令行参数不够。"
elsetotal=$[ $1 + $2 ]echo "两个命令行参数的和是$total"
fi
exit
2、${!#}
${!#}获取命令行中的最后一个参数。
#!/bin/bashecho "总共有$#个命令行参数。"
echo "其中命令行的最后一个参数是${!#}。"
exit
3、$*和$@
$*变量会将所有的命令行参数视为一个单词,而这个单词会包含命令行中出现的每一个参数。$*变量会将这些参数视为一个整体,而不是一系列个体。
$@变量则会将所有的命令行参数视为同一字符串中的多个独立的单词,方便遍历访问。
当$*出现在双引号内时,会被扩展成由多个命令行参数组成的单个单词,每个参数之间以IFS变量值的第一个字符分隔,即,“$*”会被扩展为“$1c$2c$3c...”(其中c是IFS变量值的第一个字符)
当$@出现在双引号内时,它所包含的各个命令行参数会被扩展成独立的单词,即,“$@”会被扩展为"$1""$2""$3"...
#!/bin/bashecho "使用\$*方法,参数是:$*"
count=1
for param in "$*"
doecho "\$*方法参数#$count = $param"count=$[ $count + 1 ]
done
#!/bin/bashecho "使用\$@方法,参数是:$@"
count=1
for param in "$@"
doecho "\$@方法参数 #$count = $param."count=$[ $count + 1 ]
done
echo
exit
4、移动参数shift命令
shift命令可以根据命令行参数的相对位置进行移动。默认情况下,它会将每个位置的变量值都向左移动一个位置,$3的值移入$2,$2的值移入$1,$1的值会被删除(变量$0的值是脚本名,不会改变)。如果某个参数被移除后,那么它的值就被丢弃而无法恢复了。
通过shift命令可以用来遍历命令行参数,尤其是在不知道到底有多少参数的时候,可以只操作第一个位置变量,移动参数,然后继续处理该变量。
#!/bin/bashecho #打印空行
echo "使用shift命令进行移位操作。"
count=1
while [ -n "$1" ] #测试第一个参数值的长度,当长度为0时,结束循环
doecho "参数 #$count = $1"count=$[ $count + 1 ]shift
done
echo
exit
一次性移动多个位置,只需给shift命令提供一个参数,指明要移动的位置数: shift n
#!/bin/bashecho
echo "所有的命令行参数是:$@"
echo "现在向左移动两位。"
shift 2
echo "移位后第一个参数是:$1"
echo
exit
三、处理bash命令中的选项
命令行参数是在命令/脚本名之后出现的各个单词,其中,以连字符(-)或双连字符(--)起始的参数,因为它们能够改变命令的行为,所以称作为命令行选项。命令行选项是一种特殊形式的命令行参数。
1、处理简单命令行选项
同样可以使用shift命令处理命令行选项。
#!/bin/bashecho
while [ -n $1 ]
docase "$1" in-a) echo "找到-a命令行选项。";;-b) echo "找到-b命令行选项。";;-c) echo "找到-c命令行选项。";;*) echo "$1不是一个命令行选项。";;esacshift
done
echo
exit
2、分离命令行参数和选项
在Linux中,可以使用双连字符(--)将命令行选项和参数分开。
#!/bin/bashecho
while [ -n "$1" ]
docase "$1" in-a) echo "-a是命令行选项";;-b) echo "-b是命令行选项";;-c) echo "-c是命令行选项";;--) shift #在遇到双连字符时需要将其移出位置变量,然后用break跳出while循环break;;*) echo "$1不是命令行选项"esacshift
doneecho
count=1
for param in $@
doecho "参数#$count:$param"count=$[ $count + 1 ]
done
echo
exit
不使用双连字符时
使用双连字符时
3、处理含参数的选项
有些命令行选项需要一个额外的参数值。如下所示:
#!/bin/bashecho
while [ -n "$1" ]
docase "$1" in-a) echo "-a是命令行选项";;-b) param=$2echo "-b是命令行选项,且带着参数$param"shift;;-c) echo "-c是命令行选项";;--) shift #在遇到双连字符时需要将其移出位置变量,然后用break跳出while循环break;;*) echo "$1不是命令行选项"esacshift
doneecho
count=1
for param in $@
doecho "参数#$count:$param"count=$[ $count + 1 ]
done
echo
exit
由于要处理的命令行选项位于$1,那么额外的参数值就应该在$2(前面所有的参数在处理完之后都会被移出),所以只要从$2变量中提取出来就可以了。最后,因为这个命令行选项占用了两个位置,所以还需要使用shift命令多移动一次。
只要记住放置好相应的命令行选项参数,无论按什么顺序放置命令行选项都可以。如下所示:
4、getopt命令
介绍
getopt命令可以接受一系列任意形式的命令行选项和参数,并自动将其转换成适当的形式。
格式:
getopt optstring parameters
optstring定义了有效的命令行选项的字母,同时也定义了哪些命令行选项需要参数值。
先在optstring里列出要在脚本中用到的每个命令行选项字母,其次在每个需要参数值的选项字母后面加一个冒号。
示例:getopt ab:cd -a -b Bparam -cd test1 test2
optstring定义了4个有效的命令行选项字母:a、b、c、d。冒号(:)放在了字母b的后面,表明b命令行选项需要一个参数值。当getopt命令运行时,会检查参数列表(-a -b Bparam -cd test1 test2),并基于提供的optstring进行解析。它会自动将-cd分成两个单独的命令行选项,并插入双连字符来分隔命令行中额外的参数。
如果optstring未包含用户指定的选项,就会报错。
如果想忽略这条报错,使用选项-q:
在脚本中如何使用
可以借助能够处理shell中各种变量的set命令。
set命令有一个选项是双连字符(--),它可以将位置变量的值替换成set命令所指定的值。
首先,将脚本的命令行参数传给getopt命令;然后再将getopt命令的输出传给set命令,用getopt格式化后的命令行参数来替换原始的命令行参数。
set -- $(getopt -q ab:cd "$@")
#!/bin/bash
set -- $(getopt -q ab:cd "$@")echo
while [ -n "$1" ]
docase "$1" in-a) echo "-a是命令行选项";;-b) param=$2echo "-b是命令行选项,且带着参数$param"shift;;-c) echo "-c是命令行选项";;--) shift #在遇到双连字符时需要将其移出位置变量,然后用break跳出while循环break;;*) echo "$1不是命令行选项"esacshift
doneecho
count=1
for param in $@
doecho "参数#$count:$param"count=$[ $count + 1 ]
done
echo
exit
5、getopts命令
getopt的缺点在于不擅长处理带空格和引号的参数值,如果遇到后,它会将空格当做参数分隔符,而不是根据引号将二者当做一个参数。
getopt与getopts的区别:前者在将命令行中的选项和参数处理后只生成一个输出,而后者能够和已有的shell位置变量配合默契。
getopts每次只会处理一个检测到的命令行参数,在处理完所有的参数后,getopts就会退出,同时返回一个大于0的退出状态码。使其非常适合用在解析命令行参数的循环中。
格式:
getopts optstring variable
optstring的用法与在getopt里的一致,不同的是,如果不想显示错误消息的话,可以在optstring之前加一个冒号。optstring中未定义的选项字母会以问号的形式传给脚本。
getopts命令会将当前参数保存在命令行中定义的variable中。
getopts命令需要用到两个环境变量:OPTARG和OPTIND;前者保存选项加带的参数值,后者保存参数列表中getopts正在处理的参数位置,这样在处理完当前选项之后就能继续处理其他命令行参数了。
#!/bin/bashecho
while getopts :ab:c opt
docase "$opt" ina) echo "-a是命令行选项";;b) echo "-b是命令行选项,且带着参数值$OPTARG";;c) echo "-c是命令行选项";;*) echo "未知的命令行选项:$opt";;esac
done
exit
在解析命令行选项时,getopts命令会移除起始的连字符(-),所以在case语句中不用连字符。
可以在参数值中加入空格
可以将命令行选项字母与参数值写在一起,且两者之间不加空格。
getopts命令可以将在命令行中找到的所有未定义的命令行选项统一输出成问号。
getopts命令知道何时停止处理命令行选项,并将参数值留给用户处理。在处理每个选项时,getopts都会将OPTIND环境变量值加1,处理完选项后,就可以使用shift命令和OPTIND值来移动参数。
#!/bin/bashecho
while getopts :ab:cd opt
docase "$opt" ina) echo "-a是命令行选项";;b) echo "-b是命令行选项,且带着参数值$OPTARG";;c) echo "-c是命令行选项";;d) echo "-d是命令行选项";;*) echo "未知的命令行选项:$opt";;esac
doneshift $[ $OPTIND - 1 ]
echo
count=1
for param in "$@"
doecho "参数#$count:$param"count=$[ $count + 1 ]
done
echo
exit
四、常用的Linux命令行选项
-a | 显示所有对象 |
-c | 生成计数 |
-d | 指定目录 |
-e | 扩展对象 |
-f | 指定读入数据的文件 |
-h | 显示命令的帮助信息 |
-i | 忽略文本大小写 |
-l | 产生长格式输出 |
-n | 使用非交互模式(批处理) |
-o | 将所有输出重定向至指定的文件 |
-q | 以静默模式运行 |
-r | 递归处理目录和文件 |
-s | 以静默模式运行 |
-v | 生成详细输出 |
-x | 排除某个对象 |
-y | 对所有问题回答yes |
五、获取用户输入
有时候脚本需要用户更多的交互性,比如在脚本运行时询问用户并等待用户的回答。
1、read命令
read命令从标准输入(键盘)或另一个文件描述符中接受输入,获取到输入后,它会将数据存入变量。
#!/bin/bashecho -n "请输入你的名字:" # -n选项不会在字符串末尾输出换行符,允许脚本用户紧跟其后输入数据read name
read -p "请输入你的年龄:" age # -p选项允许直接指定提示符。
days=$[ $age * 365 ]echo "你好,$name. 恭喜你,已经活了$days天。"
exit
read命令会将提示符后输入的所有数据分配给单个变量。如果指定多个变量,则输入的每个数据值都会分配给变量列表中的下一个变量,如果变量数量不够,则剩下的数据就全部分配给最后一个变量。
#!/bin/bashread -p "请输入你的姓与名:"family_name last_name
echo "你的姓是$family_name,名是$last_name"
exit
read命令中也可以不指定任何变量,如此read命令就会将接收到的所有数据都放进特殊环境变量REPLY中。REPLY环境变量包含输入的所有数据。
#!/bin/bashread -p "请输入你的姓名:"
echo
echo "你好,$REPLY!"
exit
2、超时
如果用户一直不输入,那么read命令就会一直等待,此时可以用 -t 选项指定计时器,如果计时器超时,read命令会返回一个非0的退出状态码。
#!/bin/bashif read -t 5 -p "请输入你的姓名:" name
thenecho "你的姓名是:$name"
elseechoecho "你一直没有输入,所以不再继续等待。"
fi
exit
使用read命令的 -n 选项统计输入的字符个数,当字符个数达到预期值时,就自动退出脚本,并将已输入的数据赋给变量。
#!/bin/bash# -n 1告诉read命令在接收到单个字符后就退出。
read -n 1 -p "你是否想继续?[Y/N]" answercase $answer inY | y) echoecho "好的,请继续……";;N | n) echoecho "好的,结束。"exit;;
esac
echo "脚本已结束。"
exit
3、无显示读取
从用户处得到输入,但不想在屏幕上显示出用户的输入信息,比如,输入密码。
-s 选项可以让在read命令中输入的数据出现在屏幕上(其实数据还是会被显示,只不过read命令将文本颜色设成了和背景色一样)
#!/bin/bashread -s -p "请输入你的密码:" passwd
echo
echo "你的密码是:$passwd"
exit
4、读取文件
可以使用read命令读取文件。每次调用read命令都会从指定文件中读取一行文本。当文本中没有内容可读时,read命令会退出并返回一个非0的退出状态码。
如何将文件的数据传递给read命令,最常见的方法是对文件使用cat命令,然后将结果通过管道直接传给含有read命令的while命令。
#!/bin/bashcount=1
cat $HOME/ning/test.txt | while read line
doecho "Line $count:$line"count=$[ $count + 1 ]
done
echo "已处理完该文件。"
exit
相关文章:

【Linux】处理用户输入
一、基本介绍 1、如何传递参数 向shell脚本传递数据的最基本方法就是通过命令行参数。如下,这条命令会向test.sh脚本传递10和20这两个参数。 ./test.sh 10 20 2、如何读取参数 bash shell会将所有的命令行参数都指派给称作位置参数(positional parame…...

flask后端开发(1):第一个Flask项目
目录 一、Helloworddebug、host、port的配置 gitcode地址: https://gitcode.com/qq_43920838/flask_project.git 一、Helloword 一般是会创建两个文件夹和app.py app.py from flask import FlaskappFlask(__name__)app.route(/) def hello_world():return Hello…...
Highcharts 饼图:数据可视化利器
Highcharts 饼图:数据可视化利器 引言 在数据可视化的领域中,饼图作为一种经典且直观的图表类型,被广泛应用于各种行业和场景中。Highcharts,作为一个功能强大且易于使用的JavaScript图表库,为我们提供了创建交互式和…...

黑马商城项目—服务注册、服务发现
服务注册 我们把item-service注册到Nacos,步骤如下: 1.引入依赖 在item-service的pom.xml中添加依赖: 2.配置Nacos 在item-service的application.yml中添加nacos地址配置: 3.配置服务实例 为了测试一个服务多个实例的情况,我…...
【ES6复习笔记】Map(14)
概念 Map 是 JavaScript 中的一种数据结构,它允许你存储键值对,并且可以通过键来访问对应的值。在本教程中,我们将学习如何声明、添加、删除、获取和遍历 Map 集合。 ES6 提供了 Map 数据结构。它类似于对象,也是键值对的集合。…...
15-makefile
一、Makefile的概述 1.认识make make 是一个命令,是个可执行程序,用来解析 Makefile 文件的命令;linux 环境下,这个命令存放在 /usr/bin/ 目录下;当用户输入 make 指令时,系统会自动寻找 makefile、Makef…...

yii2 手动添加 phpoffice\phpexcel
1.下载地址:https://github.com/PHPOffice/PHPExcel 2.解压并修改文件名为phpexcel 在yii项目的vendor目录下创建一个文件夹命名为phpoffice 把phpexcel目录放到phpoffic文件夹下 查看vendor\phpoffice\phpexcel目录下会看到这些文件 3.到vendor\composer目录下…...

使用 AI 辅助开发一个开源 IP 信息查询工具:一
本文将分享如何借助当下流行的 AI 工具,一步步完成一个开源项目的开发。 写在前面 在写代码时,总是会遇到一些有趣的机缘巧合。前几天,我在翻看自己之前的开源项目时,又看到了 DDNS 相关的讨论。虽然在 2021 年我写过两篇相对详细的教程&am…...
HNUST-数据分析技术课堂实验
1.要求 1,从下列第一、二、三组实验中各至少选取一个算法进行实验,选修组实验不作强制要求;2,实验过程不限,目标在于锻炼算法实现过程,即可采用C、C、Java、Python(建议)等任意语言编…...

P3456 [POI2007] GRZ-Ridges and Valleys BFS-连通块思想
题目描述 Byteasar loves trekking in the hills. During the hikes he explores all the ridges and valleys in vicinity. Therefore, in order to plan the journey and know how long it will last, he must know the number of ridgesand valleys in the area he is goi…...
WhisperKit: Android 端测试 Whisper -- Android手机(Qualcomm GPU)部署音频大模型
WhisperKit: Android 端测试 Whisper 1.环境需要2.环境构建(1)克隆项目:(2)工具检查(make setup):(3)下载模型(make download-models)(4)Docker中构建环境(ma…...
Clickhouse(Centos)
地址信息 官网地址:Fast Open-Source OLAP DBMS - ClickHouse 下载地址:packages.clickhouse.com/rpm/stable/ 1.clickhouse-client-23.1.3.5.x86_64.rpm 2.clickhouse-common-static-23.1.3.5.x86_64.rpm 3.clickhouse-common-static-dbg-23.1.3.5.x86_…...
Yolo11改进策略:Block改进|使用FastVit的RepMixerBlock改进Yolo11,重参数重构助力Yolo11涨点(全网首发)
文章目录 摘要FastViT:一种使用结构重新参数化的快速混合视觉变换器1、简介2、相关工作3、体系结构3.1、概述3.2、FastViT3.2.1、重新参数化跳过连接3.2.2、线性训练时间过参数化3.2.3、大核卷积4、实验4.1、图像分类4.2、鲁棒性评价4.3、3D Hand网格估计4.4、语义分割和目标检…...

微信小程序-基于Vant Weapp UI 组件库的Area 省市区选择
Area 省市区选择,省市区选择组件通常与 弹出层 组件配合使用。 areaList 格式 areaList 为对象结构,包含 province_list、city_list、county_list 三个 key。 每项以地区码作为 key,省市区名字作为 value。地区码为 6 位数字,前两…...
NIO(New IO)和BIO(Blocking IO)的区别
Java中的NIO(New IO)和BIO(Blocking IO)的区别及NIO的核心组件 Java中的NIO(New IO)和BIO(Blocking IO)是两种不同的网络通信模型,各自具有独特的特性和适用场景。下面将…...

ROS1入门教程6:复杂行为处理
一、新建项目 # 创建工作空间 mkdir -p demo6/src && cd demo6# 创建功能包 catkin_create_pkg demo roscpp rosmsg actionlib_msgs message_generation tf二、创建行为 # 创建行为文件夹 mkdir action && cd action# 创建行为文件 vim Move.action# 定义行为…...

碰撞检测算法之闵可夫斯基差集法(Minkowski Difference)
在游戏开发和机器人路径规划乃至于现在比较火的自动驾驶中,我们常常需要确定两个物体是否发生碰撞,有一种通过闵可夫斯基差集法求是否相交的算法,下面将介绍一下 闵可夫斯基差集法的优势 闵可夫斯基差集法优势: 可以处理复杂的…...
【唐叔学算法】第18天:解密选择排序的双重魅力-直接选择排序与堆排序的Java实现及性能剖析
引言 在数据排序的世界里,选择排序是一类简单而直观的算法,它通过不断选取未排序部分中的最小(或最大)元素来逐步构建有序序列。今天,我们将深入探讨两种基于选择思想的排序方法——直接选择排序和堆排序,…...

2008-2020年各省技术服务水平相关指标数据
2008-2020年各省技术服务水平相关指标数据 1.时间:2008-2020年 2.指标:行政区划代码、地区、年份、信息传输、软件和信息技术服务业城镇单位就业人员(万人)、软件业务收入(万元)、高技术产品出口额占商品出口额比重(%) 3.范围&…...

机器学习DAY4续:梯度提升与 XGBoost (完)
本文将通过 XGBoost 框架来实现回归、分类和排序任务,帮助理解和掌握使用 XGBoost 解决实际问题的能力。我们将从基本的数据处理开始,逐步深入到模型训练、评估以及预测。最后,将模型进行保存和加载训练好的模型。 知识点 回归任务分类任务…...
【位运算】消失的两个数字(hard)
消失的两个数字(hard) 题⽬描述:解法(位运算):Java 算法代码:更简便代码 题⽬链接:⾯试题 17.19. 消失的两个数字 题⽬描述: 给定⼀个数组,包含从 1 到 N 所有…...
JVM垃圾回收机制全解析
Java虚拟机(JVM)中的垃圾收集器(Garbage Collector,简称GC)是用于自动管理内存的机制。它负责识别和清除不再被程序使用的对象,从而释放内存空间,避免内存泄漏和内存溢出等问题。垃圾收集器在Ja…...
工程地质软件市场:发展现状、趋势与策略建议
一、引言 在工程建设领域,准确把握地质条件是确保项目顺利推进和安全运营的关键。工程地质软件作为处理、分析、模拟和展示工程地质数据的重要工具,正发挥着日益重要的作用。它凭借强大的数据处理能力、三维建模功能、空间分析工具和可视化展示手段&…...
第25节 Node.js 断言测试
Node.js的assert模块主要用于编写程序的单元测试时使用,通过断言可以提早发现和排查出错误。 稳定性: 5 - 锁定 这个模块可用于应用的单元测试,通过 require(assert) 可以使用这个模块。 assert.fail(actual, expected, message, operator) 使用参数…...

Python爬虫(一):爬虫伪装
一、网站防爬机制概述 在当今互联网环境中,具有一定规模或盈利性质的网站几乎都实施了各种防爬措施。这些措施主要分为两大类: 身份验证机制:直接将未经授权的爬虫阻挡在外反爬技术体系:通过各种技术手段增加爬虫获取数据的难度…...
Mobile ALOHA全身模仿学习
一、题目 Mobile ALOHA:通过低成本全身远程操作学习双手移动操作 传统模仿学习(Imitation Learning)缺点:聚焦与桌面操作,缺乏通用任务所需的移动性和灵活性 本论文优点:(1)在ALOHA…...

WPF八大法则:告别模态窗口卡顿
⚙️ 核心问题:阻塞式模态窗口的缺陷 原始代码中ShowDialog()会阻塞UI线程,导致后续逻辑无法执行: var result modalWindow.ShowDialog(); // 线程阻塞 ProcessResult(result); // 必须等待窗口关闭根本问题:…...
LangChain 中的文档加载器(Loader)与文本切分器(Splitter)详解《二》
🧠 LangChain 中 TextSplitter 的使用详解:从基础到进阶(附代码) 一、前言 在处理大规模文本数据时,特别是在构建知识库或进行大模型训练与推理时,文本切分(Text Splitting) 是一个…...

DAY 45 超大力王爱学Python
来自超大力王的友情提示:在用tensordoard的时候一定一定要用绝对位置,例如:tensorboard --logdir"D:\代码\archive (1)\runs\cifar10_mlp_experiment_2" 不然读取不了数据 知识点回顾: tensorboard的发展历史和原理tens…...
深入理解 React 样式方案
React 的样式方案较多,在应用开发初期,开发者需要根据项目业务具体情况选择对应样式方案。React 样式方案主要有: 1. 内联样式 2. module css 3. css in js 4. tailwind css 这些方案中,均有各自的优势和缺点。 1. 方案优劣势 1. 内联样式: 简单直观,适合动态样式和…...