shell:处理命令行参数 获取用户输入

news2024/10/6 16:24:13

1. 命令行参数

1.1 位置参数

bash shell会将一些称为位置参数(positional parameter)的特殊变量分配给输入到命令行中的 所有参数。这也包括shell所执行的脚本名称。位置参数变量是标准的数字:$0是程序名,$1是第 一个参数,$2是第二个参数,依次类推,直到第九个参数$9

读取文件名

可以用$0参数获取shell在命令行启动的脚本名。

$ cat test5.sh
#!/bin/bash 11 # Testing the $0 parameter
#
echo The zero parameter is set to: $0
# 12 $
$ bash test5.sh
The zero parameter is set to: test5.sh
$

当传给$0变量的实际字符串不仅仅是脚本名,而是完整的脚本路径时, 变量$0就会使用整个路径。

$ bash /home/Christine/test5.sh
The zero parameter is set to: /home/Christine/test5.sh 
$

basename命令会返回不包含路径的脚本名

$ cat test5b.sh
#!/bin/bash
# Using basename with the $0 parameter #
name=$(basename $0)
echo
echo The script name is: $name
#
$ bash /home/Christine/test5b.sh
The script name is: test5b.sh $
$ ./test5b.sh
The script name is: test5b.sh
$

1.2 特殊参数变量

$#
$*
$@

参数统计

特殊变量$#含有脚本运行时携带的命令行参数的个数。

抓取所有的数据

$*$@变量可以用来轻松访问所有的参数。

$*变量会将命令行上提供的所有参数当作一个单词保存。

$@变量会将命令行上提供的所有参数当作同一字符串中的多个独立的单词。

下面的例子给出了二者的差异.

$ cat test12.sh 
#!/bin/bash
# testing $* and $@
#
echo
count=1
#
for param in "$*"
do
   echo "\$* Parameter #$count = $param"
   count=$[ $count + 1 ]
done
#
echo
count=1
#
for param in "$@"
do
   echo "\$@ Parameter #$count = $param"
   count=$[ $count + 1 ]
done

$ ./test12.sh rich barbara katie jessica
$* Parameter #1 = rich barbara katie jessica
$@ Parameter #1 = rich
$@ Parameter #2 = barbara
$@ Parameter #3 = katie
$@ Parameter #4 = jessica
$

2. 移动变量shift

在使用shift命令时,默认情况下它会将每个参数变量向左移动一个位置

变量$3 的值会移到$2中,变量$2的值会移到$1中,而变量$1的值则会被删除(注意,变量$0的值,也 就是程序名,不会改变)。

$ cat test14.sh
#!/bin/bash
# demonstrating a multi-position shift
#
echo
echo "The original parameters: $*"
shift 2
echo "Here's the new first parameter: $1" $
$ ./test14.sh 1 2 3 4 5
The original parameters: 1 2 3 4 5
Here's the new first parameter: 3
$

3. 处理选项(getopt、getopts)

选项是跟在单破折线后面的单个字母,它能改变命令的行为。

3.1 使用getopt命令

getopt命令可以接受一系列任意形式的命令行选项和参数,并自动将它们转换成适当的格 式。它的命令格式如下:

getopt optstring parameters

下面是个getopt如何工作的简单例子。

$ getopt ab:cd -a -b test1 -cd test2 test3 -a -b test1 -c -d -- test2 test3
$

optstring定义了四个有效选项字母:a、b、c和d。冒号(:)被放在了字母b后面,因为b
选项需要一个参数值。

如果指定了一个不在optstring中的选项,默认情况下,getopt命令会产生一条错误消息

$ getopt ab:cd -a -b test1 -cde test2 test3 getopt: invalid option -- e
 -a -b test1 -c -d -- test2 test3
$

在脚本中使用getopt,配合set命令

方法是用getopt命令生成的格式化后的版本来替换已有的命令行选项和参数。用set命令能 够做到。

在第6章中,你就已经见过set命令了。set命令能够处理shell中的各种变量。

set命令的选项之一是双破折线(–),它会将命令行参数替换成set命令的命令行值。 然后,该方法会将原始脚本的命令行参数传给getopt命令,之后再将getopt命令的输出传给set命令,用getopt格式化后的命令行参数来替换原始的命令行参数,看起来如下所示。

 set -- $(getopt -q ab:cd "$@")

现在原始的命令行参数变量的值会被getopt命令的输出替换,而getopt已经为我们格式化 好了命令行参数。

利用该方法,现在就可以写出能帮我们处理命令行参数的脚本。

$ cat test18.sh
#!/bin/bash
# Extract command line options & values with getopt #
set -- $(getopt ab:cd "$@")
#
echo
while [ -n "$1" ]
do
       case "$1" in
       -a) echo "Found the -a option" ;;
       -b) param="$2"
           echo "Found the -b option, with parameter value $param"
           shift ;;
       -c) echo "Found the -c option" ;;
       --) shift
           break ;;
        *) echo "$1 is not an option";;
	   esac
shift done
#
count=1
for param in "$@"
do
   echo "Parameter #$count: $param"
   count=$[ $count + 1 ]
done
# $

现在如果运行带有复杂选项的脚本,就可以看出效果更好了。

$ ./test18.sh -ac
Found the -a option
Found the -c option
$

当然,之前的功能照样没有问题。

$ ./test18.sh -a -b test1 -cd test2 test3 test4
Found the -a option
Found the -b option, with parameter value 'test1'
Found the -c option
Parameter #1: 'test2'
Parameter #2: 'test3'
Parameter #3: 'test4'
$

3.2 使用getopts命令

如果选项需要跟一个参数值,OPTARG环境变量就会保存这个值。

OPTIND环境变量保存了参数列表中getopts正在处理的参数位置。

$ cat test20.sh
#!/bin/bash
# Processing options & parameters with getopts #
echo
while getopts :ab:cd opt
do
       case "$opt" in
       a) echo "Found the -a option"  ;;
       b) echo "Found the -b option, with value $OPTARG" ;;
       c) echo "Found the -c option"  ;;
       d) echo "Found the -d option"  ;;
       *) echo "Unknown option: $opt" ;;
       esac
done
#
shift $[ $OPTIND - 1 ]
#
echo
count=1
for param in "$@"
do
   echo "Parameter $count: $param"
   count=$[ $count + 1 ]
done

$
$ ./test20.sh -a -b test1 -d test2 test3 test4
Found the -a option
Found the -b option, with value test1
Found the -d option
Parameter 1: test2
Parameter 2: test3
Parameter 3: test4
$

3.3 将选项标准化

在创建shell脚本时,显然可以控制具体怎么做。你完全可以决定用哪些字母选项以及它们的 用法。

但有些字母选项在Linux世界里已经拥有了某种程度的标准含义。如果你能在shell脚本中支 6 持这些选项,脚本看起来能更友好一些。

在这里插入图片描述

4. 获取用户输入

4.1 基本读取

read命令包含了-p选项,允许你直接在read命令行指定提示符。

$ cat test22.sh
#!/bin/bash
# testing the read -p option
#
read -p "Please enter your age: " age days=$[ $age * 365 ]
echo "That makes you over $days days old! " #
$
$ ./test22.sh
Please enter your age: 10
That makes you over 3650 days old!
$

也可以在read命令行中不指定变量。如果是这样,read命令会将它收到的任何数据都放进 特殊环境变量REPLY中。

$ cat test24.sh
#!/bin/bash
# Testing the REPLY Environment variable #
read -p "Enter your name: "
echo
echo Hello $REPLY, welcome to my program. #
$
$ ./test24.sh
Enter your name: Christine
Hello Christine, welcome to my program.
$

4.2 超时

你可以用-t选项来指定一个计时器。-t选项指定了read命令等待输入的秒数。当计时器过期后,read命令会返回一个非零退出状态码。

$ cat test25.sh
#!/bin/bash
# timing the data entry
#
if read -t 5 -p "Please enter your name: " name then
       echo "Hello $name, welcome to my script"
    else
echo
       echo "Sorry, too slow! "
    fi
$
$ ./test25.sh
Please enter your name: Rich 
Hello Rich, welcome to my script 
$
$ ./test25.sh
Please enter your name: 
Sorry, too slow!
$

4.3 限制输入字符个数

-n选项限制个数

$ cat test26.sh
#!/bin/bash
# getting just one character of input
#
read -n1 -p "Do you want to continue [Y/N]? " answer 
case $answer in
Y | y) echo
       echo "fine, continue on...";;
N | n) echo
       echo OK, goodbye
       exit;;
esac
echo "This is the end of the script" $
$ ./test26.sh
Do you want to continue [Y/N]? Y fine, continue on...
This is the end of the script
$
$ ./test26.sh
Do you want to continue [Y/N]? n
OK, goodbye
$

4.4 隐藏方式读取

-s选项可以避免在read命令中输入的数据出现在显示器上(实际上,数据会被显示,只是 read命令会将文本颜色设成跟背景色一样)。这里有个在脚本中使用-s选项的例子。

$ cat test27.sh
#!/bin/bash
# hiding input data from the monitor
#
read -s -p "Enter your password: " pass
echo
echo "Is your password really $pass? " 
$
$ ./test27.sh
Enter your password:
Is your password really T3st1ng?
$

4.5 从文件中读取

最常见的方法是对文件使用cat命令,将 结果通过管道直接传给含有read命令的while命令。下面的例子说明怎么处理。

$ cat test28.sh #!/bin/bash
# reading data from a file #
count=1
cat test | while read line do
   echo "Line $count: $line"
   count=$[ $count + 1]
done
echo "Finished processing the file"
$
$ cat test
The quick brown dog jumps over the lazy fox. This is a test, this is only a test.
O Romeo, Romeo! Wherefore art thou Romeo?
$
$ ./test28.sh
Line 1: The quick brown dog jumps over the lazy fox. Line 2: This is a test, this is only a test.
Line 3: O Romeo, Romeo! Wherefore art thou Romeo?
Finished processing the file
$

while循环会持续通过read命令处理文件中的行,直到read命令以非零退出状态码退出。

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

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

相关文章

【LLM 评估】MMLU benchmark:用于衡量 LM 的多任务语言理解能力

论文:Measuring Massive Multitask Language Understanding ⭐⭐⭐⭐ ICLR 2021, arXiv:2009.03300 Code: GitHub 论文速读 本文提出了一个 benchmark:MMLU,一个覆盖了 57 个 subjects 的多项选择题的数据集。 数据集的 question 数量&…

SpringBoot-SpringBoot中文文档

简介 Spring Boot是由Pivotal团队提供的一套开源框架,可以简化spring应用的创建及部署。它提供了丰富的Spring模块化支持,可以帮助开发者更轻松快捷地构建出企业级应用。Spring Boot通过自动配置功能,降低了复杂性,同时支持基于J…

设计模式 - Observer Pattern 观察者模式

文章目录 定义观察者模式的实现构成构成UML图 观察者模式的代码实现场景代码实现 总结优点缺点应用场景 其他设计模式文章: 定义 观察者模式是行为型模式的一种,它定义对象间的一种一对多的依赖关系,使得每当一个对象改变状态,它…

Apache HBase概述(图文并茂~)

HBase概述 1. Why we need HBase ? 在大数据时代来临之前,我们通常依赖传统的关系型数据库(如RDBMS)来处理数据存储和管理。然而,随着数据量的急剧增长和数据结构的多样化,传统数据库系统开始显露出其局限性…

手写一个基于SpringBoot的MVC架构,默认实现CRUD和导入导出功能

文章目录 前言正文一、项目结构二、技术点三、部分核心代码3.1 core-tool 中的核心代码3.1.1 所有实体的通用父类 SuperEntity3.1.2 所有枚举的父接口 BaseEnum3.1.3 所有业务异常的父接口 BaseException 3.2 mvc-tool 中的核心代码3.2.1 CrudController 接口定义3.2.2 默认的C…

文心一言 VS 讯飞星火 VS chatgpt (290)-- 算法导论21.3 3题

三、给出一个包含 m 个 MAKE-SET 、UNION 和 FINDSET 操作的序列(其中有 n 个是 MAKE-SET 操作),当仅使用按秩合并时,需要 Ω(mlgn) 的时间。如果要写代码,请用go语言。 文心一言: 在并查集(Union-Find)数…

STM32使用PWM驱动WS2812_RGB灯珠

项目场景: 使用STM32标准库产生PWM实现RGB灯珠控制。 芯片型号:stm32f405rgt6 设计优点:不需要使用定时器中断资源,可以使得STM32在驱动RGB灯珠的同时能够执行其他任务。 RGB灯珠简介 项目所使用的RGB灯珠如下所示,封装…

76. UE5 RPG 实现场景阻挡剔除功能

在俯视角游戏中,我们总会碰到一个问题就是,建筑会遮挡住角色的问题。遇到这种问题有多种解决方案,厂商经常使用的一种方案是,如果角色被遮挡,则使用一种纯色或者增加一些菲涅尔的效果来实现 这种效果我之前在unity内实…

免费使用文心一言会员教程

领取&安装链接:Baidu Comate 领取季卡 有图有真相 原理:百度comate使用文心一言最新的4.0模型。百度comate目前免费使用,可以借助comate达到免费使用4.0模型目的。 如何获得 点击「Baidu Comate 领取季卡 -> 领取权益」&#xff0…

Cesium Model 中的剪裁平面 (ClippingPlane)

Cesium Model 中的剪裁平面 (ClippingPlane) 参考: https://www.cnblogs.com/webgl-angela/p/9197672.html Cesium Model 中的剪裁平面 (ClippingPlane) // 相关类: class ClippingPlaneCollection {} class ClippingPlane {}// 剪裁的整体流程: Model.prototype.update () …

Mathematica训练课(45)-- 一些常用的函数Abs[],Max[]等函数用法

①绝对值函数:Abs[]函数 ②最大值和最小值函数 ③反函数

SAP ATP可用性检查简介

Availability Check,就是可用性检查,指的是要检查一下此物料是否能满足我的需求。 接到一张销售订单(SALES ORDER),客户要求数量为100PC,并且客户要求的出货日期是2024-07-01,此时我们的销售人员肯定会想到底能否出货给客人呢?系统中建立此单时,SAP就会做一个所谓的检…

实验八 T_SQL编程

题目 以电子商务系统数据库ecommerce为例 1、在ecommerce数据库,针对会员表member首先创建一个“呼和浩特地区”会员的视图view_hohhot,然后通过该视图查询来自“呼和浩特”地区的会员信息,用批处理命令语句将问题进行分割,并分…

17859划分准则小结

17859《划分准则》 发布时间:1999.9.13 实施时间:2001.1.1 计算机信息系统安全保护能力的五个等级: 第一级:用户自主保护级 第二级…

Java知识点整理 15 — MyBatis框架

一. 什么是 MyBatis MyBatis 是一款优秀的持久层框架,支持自定义 SQL、存储过程以及高级映射。它免除了几乎所有 JDBC代码以及手动设置参数和获取结果集的工作。MyBatis 可以通过简单的 XML 或注解来配置和映射原始类型、接口和 Java POJO(普通老式 Jav…

人脑网络的多层建模与分析

摘要 了解人类大脑的结构及其与功能的关系,对于各种应用至关重要,包括但不限于预防、处理和治疗脑部疾病(如阿尔茨海默病或帕金森病),以及精神疾病(如精神分裂症)的新方法。结构和功能神经影像学方面的最新进展,以及计算机科学等…

决定佛蒙特州版图的关键历史事件:

​决定佛蒙特州版图的关键历史事件: 1. 早期探险与命名: - 1609年,法国探险家萨缪尔德尚普兰(Samuel de Champlain)到达了现在的佛蒙特州区域,并探索了尚普兰湖(Lake Champlain)。他将周围的山…

mwwz库添加对多模板匹配的支持:find_shape_models

多模板匹配的实现只需要对单模板匹配做一些扩展,传入的模板由不同的id表示,在金字塔顶层完成模板的分类,在剩下的金字塔完成对每一类模板的匹配,匹配结果由id标识。测试程序已集成该方法,清除模板后所创建的模板被看作…

Python基于决策树分类模型、支持向量机分类模型、随机森林分类模型和XGBoost分类模型实现月亮数据标签预测项目实战

说明:这是一个机器学习实战项目(附带数据代码文档视频讲解),如需数据代码文档视频讲解可以直接到文章最后获取。 1.项目背景 在探索机器学习算法的性能与适用性时,我们往往需要依赖于精心设计的人工数据集来测试和验证…

全面对标GPT-4 Turbo,讯飞星火V4.0凭什么?

大数据产业创新服务媒体 ——聚焦数据 改变商业 自从ChatGPT爆火出圈之后,大模型就走上了发展的快车道。 一方面,大模型技术快速演进,Sora为我们打开了视频生成的想象空间,各大厂商争相打破大模型的“模态墙”,长文本…