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

ops/2025/1/16 6:51:49/

1. 命令行参数

1.1 位置参数

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

读取文件名

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

bash">$ 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">$ bash /home/Christine/test5.sh
The zero parameter is set to: /home/Christine/test5.sh 
$

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

bash">$ 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 特殊参数变量

bash">$#
$*
$@

参数统计

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

抓取所有的数据

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

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

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

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

bash">$ cat test12.sh 
#!/bin/bash
# testing $* and $@
#
echo
count=1
#
for param in "$*"
doecho "\$* Parameter #$count = $param"count=$[ $count + 1 ]
done
#
echo
count=1
#
for param in "$@"
doecho "\$@ 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的值,也 就是程序名,不会改变)。

bash">$ 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命令可以接受一系列任意形式的命令行选项和参数,并自动将它们转换成适当的格 式。它的命令格式如下:

bash">getopt optstring parameters

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

bash">$ 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命令会产生一条错误消息

bash">$ 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格式化后的命令行参数来替换原始的命令行参数,看起来如下所示。

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

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

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

bash">$ cat test18.sh
#!/bin/bash
# Extract command line options & values with getopt #
set -- $(getopt ab:cd "$@")
#
echo
while [ -n "$1" ]
docase "$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" ;;--) shiftbreak ;;*) echo "$1 is not an option";;esac
shift done
#
count=1
for param in "$@"
doecho "Parameter #$count: $param"count=$[ $count + 1 ]
done
# $

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

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

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

bash">$ ./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正在处理的参数位置。

bash">$ cat test20.sh
#!/bin/bash
# Processing options & parameters with getopts #
echo
while getopts :ab:cd opt
docase "$opt" ina) 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 "$@"
doecho "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命令行指定提示符。

bash">$ 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中。

bash">$ 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命令会返回一个非零退出状态码。

bash">$ cat test25.sh
#!/bin/bash
# timing the data entry
#
if read -t 5 -p "Please enter your name: " name thenecho "Hello $name, welcome to my script"else
echoecho "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选项限制个数

bash">$ 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) echoecho "fine, continue on...";;
N | n) echoecho OK, goodbyeexit;;
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选项的例子。

bash">$ 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命令。下面的例子说明怎么处理。

bash">$ cat test28.sh #!/bin/bash
# reading data from a file #
count=1
cat test | while read line doecho "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.ppmy.cn/ops/53468.html

相关文章

【面试干货】与的区别:位运算符与逻辑运算符的深入探讨

【面试干货】&与&&的区别:位运算符与逻辑运算符的深入探讨 1、&:位运算符2、&&:逻辑运算符3、&与&&的区别 💖The Begin💖点点关注,收藏不迷路💖 & 和 …

MySQL的高级查询语句

高级查询语句 前言基本查询指定指字段进行查看对字段进行去重查看where条件查询逻辑关系的增加查询逻辑关系的减少查询查询取值列表中的数据between的方式like的方式 排序方式进行查询 运用函数查询数据库中常用数学的函数聚合函数求平均值统计非空值查询“最”值求和 字符串函…

免杀笔记 ---> C语言

这次的更新可能有点慢,因为这段时间也比较忙,加上C语言还得和汇编结合,导致小编一个知识点总是得反复揣摩(太菜了),所以免杀的更新篇幅长度可能会达到两个月和三个月,但是小编能保证&#xff0c…

基于CSDN的Markdown文本编辑器的博客界面优化 | HTML | 文本标签 | 图像标签 | 个人主页引导

🙋大家好!我是毛毛张! 🌈个人首页: 神马都会亿点点的毛毛张 今天毛毛张分享的内容是如何在CSDN的Markdown编辑器中实现上图的效果,如果觉得能帮助到你的话就点击个人主页点点关注吧❗ 文章目录 1.前言2.基础知识3.字…

Js逆向爬虫基础篇

这里写自定义目录标题 逆向技巧断点一 、请求入口定位1. 关键字搜索2. 请求堆栈3. hook4. JSON.stringify 二、响应入口定位:1. 关键字搜索2. hook3. JSON.parse 逆向技巧 断点 普通断点 条件断点 日志断点 XHR断点 一 、请求入口定位 1. 关键字搜索 key关…

RocketMQ源码学习笔记:Broker接受消息和发送消息

这是本人学习的总结,主要学习资料如下 马士兵教育rocketMq官方文档 目录 1、Overview2、技术亮点2.1、消息写入时的自旋锁和可重入锁2.2、堆外内存机制2.2.1、Overview2.2.2、源码2.2.2.1、开启堆外内存的条件2.2.2.2、堆外内存的初始化2.2.2.3、写消息到堆外内存2…

java调用海康威视SDK实现车牌识别

我采用的是 报警布防方式 SDK版本为 CH-HCNetSDKV6.1.9.48_build20230410_win32 如何引用dll 我用的是jna 就不描述了 SDK在官网自行下载 以下代码亲测可用 自行参考~ 1.1接口调用流程 虚线框的内容是可选的,设备事先安装配置好,能力集和配置接口可…

高可用电商返利APP架构设计与实现分享

高可用电商返利APP架构设计与实现分享 大家好,我是免费搭建查券返利机器人省钱赚佣金就用微赚淘客系统3.0的小编,也是冬天不穿秋裤,天冷也要风度的程序猿!今天我们将深入探讨高可用电商返利APP的架构设计与实现,这是保…