Shell编程—用户输入
1命令行参数
1.1读取参数
bash shell会将一些称为位置参数(positional parameter)的特殊变量分配给输入到命令行中的所有参数。这也包括shell所执行的脚本名称。位置参数变量是标准的数字:$0是程序名,$1是第一个参数,$2是第二个参数,依次类推,直到第九个参数$9。
例子:计算阶乘
$ vim test1.sh
#!/bin/bash
# using one command line parameter
factorial=1
for (( number = 1; number <= $1 ; number++ ))
do
factorial=$[ $factorial * $number ]
done
echo The factorial of $1 is $factorial $ ./test1.sh 5
The factorial of 5 is 120
1.2读取脚本名
以用$0参数获取shell在命令行启动的脚本名。
$ cat test5.sh
#!/bin/bash
# Testing the $0 parameter
echo The zero parameter is set to: $0 $bash test5.sh
The zero parameter is set to: test5.sh
但是这里存在一个潜在的问题。如果使用另一个命令来运行shell脚本,命令会和脚本名混在一起,出现在$0参数中。比如:
$ ./test5.sh
The zero parameter is set to: ./test5.sh
$ bash /home/Christine/test5.sh
The zero parameter is set to: /home/Christine/test5.sh
这个时候basename命令可以帮助我们,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
可以用这种方法来编写基于脚本名执行不同功能的脚本。这里有个简单的例子:
$ cat test6.sh
#!/bin/bash
name=$(basename $0)
#判断参数是否为空,如果为空的话(就是执行脚本时少带了参数),后面的脚本会报错
if [ -e $1 ]
then
echo "\$1 is empty"
exit 1
elif [ -e $2 ]
then
echo "\$2 is empty"
exit 1
fi if [ $name = "addem" ]
then
total=$[ $1 + $2 ]
elif [ $name = "multem" ]
then
total=$[ $1 * $2 ]
fi
echo The calculated value is $total 开始测试:
$ cp test6.sh addem
$ chmod u+x addem
$ ln -s test6.sh multem
$ ls -l *em
-rwxrw-r--. 1 Christine Christine 224 Jun 30 23:50 addem
lrwxrwxrwx. 1 Christine Christine 8 Jun 30 23:50 multem -> test6.sh $ ./addem 2 5
The calculated value is 7 $ ./multem 2 5
The calculated value is 10
本例从test6.sh脚本中创建了两个不同的文件名:一个通过复制文件创建(addem),另一个通过链接创建(multem)。在两种情况下都会先获得脚本的基本名称,然后根据该值执行相应的功能。
2特殊参数变量
2.1参数统计
特殊变量$#:含有脚本运行时携带的命令行参数的个数
$ cat test8.sh
#!/bin/bash
# getting the number of parameters
echo There were $# parameters supplied. $ ./test8.sh
There were 0 parameters supplied. $ ./test8.sh 1 2 3 4 5
There were 5 parameters supplied. $ ./test8.sh 1 2 3 4 5 6 7 8 9 10
There were 10 parameters supplied. $ ./test8.sh "Rich Blum"
There were 1 parameters supplied.
如果要直接获取最后一个参数的值时,不应该用${$#},而是应该用${!#}:
2.2抓取所有的数据
$*和$@变量可以用来轻松访问所有的参数。这两个变量都能够在单个变量中存储所有的命令行参数。
$*变量会将命令行上提供的所有参数当作一个单词保存,这个单词包含了命令行中出现的每一个参数值;
$@变量会将命令行上提供的所有参数当作同一字符串中的多个独立的单词。
例子:
$ cat test10.sh
#!/bin/bash
# Grabbing the last parameter
params=$#
echo echo The last parameter is $params
echo The last parameter is ${!#} $ bash test10.sh 1 2 3 4 5
The last parameter is 5
The last parameter is 5 $ bash test10.sh
The last parameter is 0
The last parameter is test10.sh
3移动变量
shift命令能够用来操作命令行参数。它会根据相对位置来移动命令行参数。在使用shift命令时,默认情况下它会将每个参数变量向左移动一个位置。所以,变量$3的值会移到$2中,变量$2的值会移到$1中,而变量$1的值则会被删除(注意,变量$0的值,也就是程序名,不会改变)。
$ cat test13.sh
#!/bin/bash
count=1
while [ -n "$1" ]
do
echo "Parameter #$count = $1"
count=$[ $count + 1 ]
shift
done $ ./test13.sh rich barbara katie jessica
Parameter #1 = rich
Parameter #2 = barbara
Parameter #3 = katie
Parameter #4 = jessica
另外,你也可以一次性移动多个位置,只需要给shift命令提供一个参数,指明要移动的位置数就行了。
$ cat test14.sh
#!/bin/bash
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
4处理选项
1. 处理简单选项
$ cat test15.sh
#!/bin/bash
# extracting command line options as parameters
while [ -n "$1" ]
do
case "$1" in
-a) echo "Found the -a option" ;;
-b) echo "Found the -b option" ;;
-c) echo "Found the -c option" ;;
*) echo "$1 is not an option" ;;
esac
shift
done $ ./test15.sh -a -b -c -d
Found the -a option
Found the -b option
Found the -c option
-d is not an option
2. 分离参数和选项
双破折线(--):表明选项列表结束。
$ cat test16.sh
#!/bin/bash
while [ -n "$1" ]
do
case "$1" in
-a) echo "Found the -a option" ;;
-b) echo "Found the -b option";;
-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 $ ./test16.sh -c -a -b test1 test2 test3
Found the -c option
Found the -a option
Found the -b option
test1 is not an option
test2 is not an option
test3 is not an option $ ./test16.sh -c -a -b -- test1 test2 test3
Found the -c option
Found the -a option
Found the -b option
Parameter #1: test1
Parameter #2: test2
Parameter #3: test3
3. 处理带值的选项
$ cat test17.sh
#!/bin/bash
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 $ ./test17.sh -a -b test1 -d
Found the -a option
Found the -b option, with parameter value test1
-d is not an option
但是这种脚本遇到$ ./test17.sh -ac的命令九九没法执行了。
5将选项标准化
|
选 项 |
描 述 |
|
-a |
显示所有对象 |
|
-c |
生成一个计数 |
|
-d |
指定一个目录 |
|
-e |
扩展一个对象 |
|
-f |
指定读入数据的文件 |
|
-h |
显示命令的帮助信息 |
|
-i |
忽略文本大小写 |
|
-l |
产生输出的长格式版本 |
|
-n |
使用非交互模式(批处理) |
|
-o |
将所有输出重定向到的指定的输出文件 |
|
-q |
以安静模式运行 |
|
-r |
递归地处理目录和文件 |
|
-s |
以安静模式运行 |
|
-v |
生成详细输出 |
|
-x |
排除某个对象 |
|
-y |
对所有问题回答yes |
6获得用户输入
6.1基本的读取
read命令从标准输入(键盘)或另一个文件描述符中接受输入。在收到输入后,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!
6.2 超时
使用read命令时要当心。脚本很可能会一直苦等着脚本用户的输入。如果不管是否有数据输入,脚本都必须继续执行,你可以用-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!
如果计时器过期,read命令会以非零退出状态码退出,可以使用如if-then语句或while循环这种标准的结构化语句来理清所发生的具体情况。
也可以不对输入过程计时,而是让read命令来统计输入的字符数。当输入的字符达到预设的字符数时,就自动退出,将输入的数据赋给变量。
$ 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 "fine, continue on…";;
N | n) 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
本例中将-n选项和值1一起使用,告诉read命令在接受单个字符后退出。只要按下单个字符回答后,read命令就会接受输入并将它传给变量,无需按回车键。
Shell编程—用户输入的更多相关文章
- Shell 读取用户输入
14.2 读取用户输入 14.2.1 变量 上一章我们谈到如何定义或取消变量,变量可被设置为当前shell的局部变量,或是环境变量.如果您的shell脚本不需要调用其他脚本,其中的变量通常设置为脚 ...
- shell获取用户输入
主题: 再学shell之获取用户输入echo -n(不换行)和read命令-p(提示语句) -n(字符个数) -t(等待时间) -s(不回显) 和“读文件”深入学习 1.基本读取read命令接收标准输 ...
- linux shell获取用户输入
一.获取用户输入1.基本读取read命令接收标准输入的输入,或其它文件描述符的输入.得到输入后,read命令将数据输入放入一个标准变量中.[root@rac2 ~]# cat t8.sh #!/bin ...
- Shell编程笔记
Shell编程笔记与Windows下熟悉的批处理类似,也可以将一些重复性的命令操作写成一个脚本方便处理. 修改别人的脚本,运行后遇到个问题 setenv: command not found 查证 ...
- SHELL编程入门简介
一.SHELL软件概念和应用场景 1) 学习Linux技术,不是为了学习系统安装.命令操作.用户权限.配置IP.网络管理,学习Linux技术重点:基于Linux系统部署和维护各种应用软件.程序(Apa ...
- shell编程中用户输入处理(shell 04)
shell编程中用户输入处理1.命令行参数2.脚本运行时获取输入 命令行参数 通过空格来进行分割的位置参数 :$+position $0,$1,$2 ....$0 :程序名$1,$2,$3 ... $ ...
- 《Linux命令行与shell脚本编程大全》第十四章 处理用户输入
有时还会需要脚本能够与使用者交互.bash shell提供了一些不同的方法来从用户处获得数据, 包括命令行参数,命令行选项,以及直接从键盘读取输入的能力. 14.1 命令行参数 就是添加在命令后的数据 ...
- 一、Vim编辑器 二、用户和组管理 三、软件的安装(jdk,mysql) 四、Shell编程
一.Vim编辑器的使用 1. vim编辑器的运行模式 编辑模式:等待用户编辑命令的输入 插入模式:编辑文本内容 命令模式:执行命令 2. 使用 :vim 文件名 3. 查看当前vim编辑器介绍:vim ...
- centos 下建用户 shell编程
useradd 用户名 passwd 用户名 cat /etc/passwd 查看用户信息 删除用户 userdel -r 加一个 -r 表示把用户及用户的主目录都删除 su 切换用户 sud ...
随机推荐
- Day03_破解Windows7系统密码&用户与组管理&服务器远程管理
破解Windows系统密码 一.利用5次shift漏洞破解win7密码 1.1 漏洞 1.在未登录系统时,连续按5次shift键,弹出程序c:\windows\system32\sethc.exe 2 ...
- Radiobutton基础语法
.Radiobutton(root 主窗口,text 文本内容,value 值(可以通过set 和 get 获取到的值),variable 变量修改原来的StringVar) self.radio_m ...
- PHP 怎么安装
您需要做什么? 为了开始使用 PHP,您可以: 找一个支持 PHP 和 MySQL 的 Web 主机 在您自己的 PC 机上安装 Web 服务器,然后安装 PHP 和 MySQL 使用支持 PHP 的 ...
- Qt自定义控件之仪表盘2--QPaint绘制仪表盘
0.前言 前面一篇文章写道了仪表盘的特点,实现了一个贴图的仪表盘,属于低配版本的仪表盘. 主要是有任何改动时候就需要重新设计图片,不能适配不同控件大小,即使让它自由拉伸,但仪表盘放大缩小时候显示 ...
- XSSFWorkbook
支持2007以后的 此类与HSSFWorkbook(支持2007之前) 类似,读取文件时把全部的内容都存放到内存中,关闭输入流后. 内存与硬盘完全是毫无关系的两份数据,所有的操作都是对内存的操作,最后 ...
- 07 . ELK Stack一键多机部署脚本
一键部署脚本 目录结构 tree Log_Analysis_Platform_Document Log_Analysis_Platform_Document ├── InstallES.sh ├── ...
- 【SCOI2008】奖励关 题解(状压DP+期望)
题目链接 题目大意:给定$n$个宝物,每次随机抛出一个宝物,奖励分数为$p_i$.但如果选这个宝物必须选过它的前置宝物集合.共进行$K$轮问最优策略下的期望. $n\leq 15,-10^6\leq ...
- Android 菜单的使用
有时间就随笔记录自己遇到的问题和所学的知识哈. 这是对本牛崽知识的提升也可以给其他牛牛们来点鸡汤和开胃菜. 菜单Menu的创建 首先menu是属于布局的嘛,所以嘞,咱们得在res(也就是布局资源)创建 ...
- 关于Linux目录访问函数总结
Linux下目录访问函数总结,主要是涉及到的函数,以及所在头文件. 获得工作目录: #include <unistd.h> char *getcwd(char *buf,s ...
- mysql存储引擎InnoDB详解,从底层看清InnoDB数据结构
InnoDB一个支持事务安全的存储引擎,同时也是mysql的默认存储引擎.本文主要从数据结构的角度,详细介绍InnoDB行记录格式和数据页的实现原理,从底层看清InnoDB存储引擎. 本文主要内容是根 ...