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

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命令以非零退出状态码退出。

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

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

相关文章

基于C语言的Jacobi迭代和Gauss-Seidel迭代的方程组求解实现

文章目录 Jacobi迭代方法介绍Gauss-Seidel迭代方法介绍具体代码实现示例题目实现效果 Jacobi迭代方法介绍 Jacobi迭代法是一种简单的迭代求解方法,适用于严格对角占优矩阵。其基本思想是利用当前迭代步的已知解来更新下一个迭代步的解。在C语言实现中,我…

网格处理库 pmp-library 编译及应用笔记 -- 已全部解决√

多边形网格处理库Polygon Mesh Processing Library,简称pmp-library的 编译及应用笔记 – 已全部解决√ 官网:https://www.pmp-library.org/index.html 代码:https://github.com/pmp-library/pmp-library 平台:Ubuntu1 20.04&…

Python功能制作之使用streamlit做一个简单的WebUI

使用Streamlit创建WebUI 1. 什么是Streamlit Streamlit 是一个开源的Python库,用于快速创建美观的Web应用。 它适合数据科学家和机器学习工程师,因为它能够以最小的代码量将数据应用程序带到浏览器中。通过简单的Python脚本,可以创建交互式…

C++中的三大池:线程池,内存池,数据库连接池

C中有三大池,即我们常说的:线程池,内存池,数据库连接池。 一.线程池 多线程同时访问共享资源造成数据混乱的原因就是因为CPU的上下文切换导致,线程池就是为了解决此问题而生。 多线程常用的有:std::threa…

基于Spring Boot的校园失物招领系统

1 项目介绍 1.1 研究的背景及意义 在网络时代飞速发展的今天,随着网络技术日臻完善,我们的生活方式正经历深刻变革。在物质追求日益增长的同时,提升个人精神境界也成为了现代人的共同向往,而阅读则是滋养心灵、丰富精神世界的重…

【SpringBoot3学习 | 第1篇】SpringBoot3介绍与配置文件

文章目录 前言 一. SpringBoot3介绍1.1 SpringBoot项目创建1. 创建Maven工程2. 添加依赖(springboot父工程依赖 , web启动器依赖)3. 编写启动引导类(springboot项目运行的入口)4. 编写处理器Controller5. 启动项目 1.2 项目理解1. 依赖不需要写版本原因2. 启动器(Starter)3. Sp…

C++——探索智能指针的设计原理

前言: RAII是资源获得即初始化, 是一种利用对象生命周期来控制程序资源地手段。 智能指针是在对象构造时获取资源, 并且在对象的声明周期内控制资源, 最后在对象析构的时候释放资源。注意, 本篇文章参考——C 智能指针 - 全部用法…

Arduino - TM1637 4 位 7 段显示器

Arduino - TM1637 4 位 7 段显示器 Arduino-TM1637 4 位 7 段显示器 A standard 4-digit 7-segment display is needed for clock, timer and counter projects, but it usually requires 12 connections. The TM1637 module makes it easier by only requiring 4 connectio…

电通出席2024年世界经济论坛(WEF),重申推动可持续发展创新和人才培育的承诺

中国,上海——电通将出席世界经济论坛2024年新领军者年会(夏季达沃斯),本次大会将于6月25日至6月27日在中国大连举行。 2024年世界经济论坛主题为“未来增长的新前沿”,将聚焦于全球经济复苏、通胀缓解,以…

计算机毕业设计Python+Spark知识图谱微博预警系统 微博推荐系统 微博可视化 微博数据分析 微博大数据 微博爬虫 微博预测系统 大数据毕业设计

课题名称 基于Bert模型对微博的言论情感分析设计与实现 课题来源 课题类型 BY 指导教师 学生姓名 专 业 计算机科学与技术 学 号 开题报告内容:(调研资料的准备,设计/论文的目的、要求、思路与预期成果;…

汽车免拆诊断案例 | 2016 款吉利帝豪EV车无法加速

故障现象 一辆2016款吉利帝豪EV车,累计行驶里程约为28.4万km,车主反映车辆无法加速。 故障诊断 接车后路试,行驶约1 km,踩下加速踏板,无法加速,车速为20 km/h左右,同时组合仪表上的电机及控制…

CST--如何在PCB三维模型中自由创建离散端口

在使用CST电磁仿真软件进行PCB的三维建模时,经常会遇到不能自动创建离散端口的问题,原因有很多,比如:缺少元器件封装、开路端口、多端子模型等等,这个时候,很多人会选择手动进行端口创建,但是&a…

centos 7.2 离线部署 mysql 5.7.37

1.安装依赖 清楚mysql从图的依赖 rpm -qa|grep mariadb 存在冲突依赖,进行卸载 rpm -e --nodeps mariadb-libs-5.5.44-2.el7.centos.x86_64 确认gcc版本 ldd --version 安装mysql5.7所需要的依赖 mkdir -p /root/AllInstalls 只下载不安装,用于放到其他机器: yum inst…

Java对象创建过程

在日常开发中,我们常常需要创建对象,那么通过new关键字创建对象的执行中涉及到哪些流程呢?本文主要围绕这个问题来展开。 类的加载 创建对象时我们常常使用new关键字。如下 ObjectA o new ObjectA();对虚拟机来讲首先需要判断ObjectA类的…

一款轻量级的通信协议---MQTT (内含Linux环境搭建)

目录 MQTT MQTT的关键特点: 应用场景 Linux环境搭建: 1. 安装mosquitto 2. Linux下客户端进行通信 3. PC端和Linux下进行通信 安装MQTT. fx 4. MQTT.fx的使用 1. 点击连接 ​编辑 2. 连接成功 3. 订阅主题或者给别的主题发送消息 遇到的问…

Qt 5.14.2+Android环境搭建

1. 安装QT5.14.2的过程中,选中套件(kit) qt for android。 如果已经安装了qt creator但没有安装该套件,可以找到在qt安装目录下的MaintenanceTool.exe,运行该程序添加套件。 2. 安装jdk8,android sdk&…

2.1 大语言模型的训练过程 —— 《带你自学大语言模型》系列

《带你自学大语言模型》系列部分目录及计划,完整版目录见: 带你自学大语言模型系列 —— 前言 第一部分 走进大语言模型(科普向) 第一章 走进大语言模型1.1 从图灵机到GPT,人工智能经历了什么?1.2 如何让…

【全球首个开源AI数字人】DUIX数字人-打造你的AI伴侣!

目录 1. 引言1.1 数字人技术的发展背景1.2 DUIX数字人项目的开源意义1.3 DUIX数字人技术的独特价值1.4 本文目的与结构 2. DUIX数字人概述2.1 定义与核心概念2.2 硅基智能与DUIX的关系2.3 技术架构2.4 开源优势2.5 应用场景2.6 安全与合规性 3. DUIX数字人技术特点3.1 开源性与…

数据结构-分析期末选择题考点(图)

我是梦中传彩笔 欲书花叶寄朝云 目录 图的常见考点(一)图的概念题 图的常见考点(二)图的邻接矩阵、邻接表 图的常见考点(三)拓扑排序 图的常见考点(四)关键路径 图的常见考点&#x…

List接口, ArrayList Vector LinkedList

Collection接口的子接口 子类Vector,ArrayList,LinkedList 1.元素的添加顺序和取出顺序一致,且可重复 2.每个元素都有其对应的顺序索引 方法 在index 1 的位置插入一个对象,list.add(1,list2)获取指定index位置的元素&#…