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编程—用户输入的更多相关文章

  1. Shell 读取用户输入

    14.2  读取用户输入 14.2.1  变量 上一章我们谈到如何定义或取消变量,变量可被设置为当前shell的局部变量,或是环境变量.如果您的shell脚本不需要调用其他脚本,其中的变量通常设置为脚 ...

  2. shell获取用户输入

    主题: 再学shell之获取用户输入echo -n(不换行)和read命令-p(提示语句) -n(字符个数) -t(等待时间) -s(不回显) 和“读文件”深入学习 1.基本读取read命令接收标准输 ...

  3. linux shell获取用户输入

    一.获取用户输入1.基本读取read命令接收标准输入的输入,或其它文件描述符的输入.得到输入后,read命令将数据输入放入一个标准变量中.[root@rac2 ~]# cat t8.sh #!/bin ...

  4. Shell编程笔记

    Shell编程笔记与Windows下熟悉的批处理类似,也可以将一些重复性的命令操作写成一个脚本方便处理.   修改别人的脚本,运行后遇到个问题 setenv: command not found 查证 ...

  5. SHELL编程入门简介

    一.SHELL软件概念和应用场景 1) 学习Linux技术,不是为了学习系统安装.命令操作.用户权限.配置IP.网络管理,学习Linux技术重点:基于Linux系统部署和维护各种应用软件.程序(Apa ...

  6. shell编程中用户输入处理(shell 04)

    shell编程中用户输入处理1.命令行参数2.脚本运行时获取输入 命令行参数 通过空格来进行分割的位置参数 :$+position $0,$1,$2 ....$0 :程序名$1,$2,$3 ... $ ...

  7. 《Linux命令行与shell脚本编程大全》第十四章 处理用户输入

    有时还会需要脚本能够与使用者交互.bash shell提供了一些不同的方法来从用户处获得数据, 包括命令行参数,命令行选项,以及直接从键盘读取输入的能力. 14.1 命令行参数 就是添加在命令后的数据 ...

  8. 一、Vim编辑器 二、用户和组管理 三、软件的安装(jdk,mysql) 四、Shell编程

    一.Vim编辑器的使用 1. vim编辑器的运行模式 编辑模式:等待用户编辑命令的输入 插入模式:编辑文本内容 命令模式:执行命令 2. 使用 :vim 文件名 3. 查看当前vim编辑器介绍:vim ...

  9. centos 下建用户 shell编程

    useradd 用户名 passwd 用户名 cat /etc/passwd  查看用户信息 删除用户 userdel -r   加一个 -r 表示把用户及用户的主目录都删除 su  切换用户 sud ...

随机推荐

  1. PHP fscanf() 函数

    定义和用法 fscanf() 函数根据指定的格式对来自打开的文件的输入进行解析. 语法 fscanf(file,format,mixed) 参数 描述 file 必需.规定要检查的文件. format ...

  2. PHP time_nanosleep() 函数

    实例 延迟执行当前脚本 3,5 秒: <?phpif (time_nanosleep(3,500000000) === true){高佣联盟 www.cgewang.comecho " ...

  3. luogu P6088 [JSOI2015]字符串树 可持久化trie 线段树合并 树链剖分 trie树

    LINK:字符串树 先说比较简单的正解.由于我没有从最简单的考虑答案的角度思考 所以... 下次还需要把所有角度都考察到. 求x~y的答案 考虑 求x~根+y~根-2*lca~根的答案. 那么问题变成 ...

  4. KMP,HASH,Trie,AC自动机

    我做个总结算了下午看了一下AC自动机和学习我的大生物(当然是多谢鑫神了)..完了要崩.. 1 KMP 只要是学过的人都觉得比较简单吧 但是学不会的人就感觉很难了,我是那种顿悟的然后感觉非常简单的人过程 ...

  5. IDEA、maven创建webapp项目

      maven官方入门指南:http://maven.apache.org/guides/getting-started/index.html 推荐跟着官方文档学习噢~   IDEA.maven创建w ...

  6. Qt自定义控件之仪表盘2--QPaint绘制仪表盘

    0.前言 前面一篇文章写道了仪表盘的特点,实现了一个贴图的仪表盘,属于低配版本的仪表盘.    主要是有任何改动时候就需要重新设计图片,不能适配不同控件大小,即使让它自由拉伸,但仪表盘放大缩小时候显示 ...

  7. Spring 参数注入

    一个(类)Bean可能包含多种属性,这些属性怎么配置???  见下: 用People  Dog Cat Tiger  Panda五个类来学习一些常用的=_= 重点在XML <!--基本类型注入- ...

  8. requests上传文件,又要上传data的处理

    前话 最近在自己学着弄接口自动化框架,因为要封装一个发送请求的父类,其中有考虑到上传文件,以及同时上传文件,和传递其他字段数据,遇到点小问题 这里解决下. 实例的接口数据 参考文档 来自fastapi ...

  9. python字符串和数字的基本运算符

    python字符穿的4种表达方式 name='张三' name="张三" name='''张三''' name="""张三""&q ...

  10. 在centOS7上安装一套java运行环境

    前提:更换centos的默认yum源,提高下载速度. 备份系统自带的yum源 mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS- ...