bash shell笔记4 处理用…
知识体系:
#使用命令行参数
#设置选项
#获取用户输入
有时编写的脚本需要能和运行脚本的人员进行交互,bash
shell提供了一些方法来从用户处获取数据,这些方法有如下三种:
1- 命令行参数(添加在命令后的参数)
2- 命令行选项(修改命令行为的单字符串)
3- 直接读取键盘输入
1、命令行参数
向shell脚本传递数据最基本的方式就是命令行参数,主要就是说通过一些特殊变量是的bash
shell自动把输入的参数赋值给变量才执行脚本。这些变量叫做位置参数,分别有$1为第一个参数、$2为第二个参数、$0为程序名称。。。
1.1、读取参数
如下看个例子就能理解这个位置参数的概念了:
[root@wzp ~]# chmod u+x 1.1test
[root@wzp ~]# cat 1.1test
#!/bin/bash
a=1
for (( b=1; b<=$1; b++ ))
do
a=$[ $a * $b ]
done
echo the factorial of $1 is $a
[root@wzp ~]# ./1.1test 5
the factorial of 5 is 120
[root@wzp ~]# ./1.1test 4
the factorial of 4 is 24
主要来看./xx后面附带的命令行参数,只有一个参数也即为第一个参数很明显赋值为$1,通过for循环计算出累乘结果,所以你输入的第一个参数值改变了,结果也就随着改变。
如果要输入更多的命令行参数,那么每个命令行参数必须使用空格分隔出来,下面看一个例子:
[root@wzp
~]# cat 1.1test
#!/bin/bash
total=$[ $1 * $2 ]
echo the first param is $1
echo the second param is $2
echo the total value is $total
[root@wzp ~]# ./1.1test 2 3
the first param is 2
the second param is 3
the total value is 6
[root@wzp ~]# ./1.1test 4 7
the first param is 4
the second param is 7
the total value is 28
如上脚本很容易理解,我们看到2/3和4/7都分别被赋值给$1和$2,这里就是通过命令行参数之间的空格分开实现的。当然,数值可以给赋值,对于文本字符串也是可以的,如果要将出现空格的连于一体的参数值可以通过单引号或者双引号括起来,这样bash
shell就将其视为一个参数值,先来看个例子:
[root@wzp
~]# cat 1.1test
#!/bin/bash
echo hello $1,glad to meet you.
[root@wzp ~]# ./1.1test 51cto gdin
hello 51cto,glad to meet you.
[root@wzp ~]# ./1.1test 'netease corporation'
hello netease corporation,glad to meet you.
对于脚本中没有附带$2变量则把gdin参数忽略了。
还有一点必须说明的:
如果脚本输入的命令参数多于9个,就必须使用大括号把变量括起来,如{10},来看个例子:
[root@wzp
~]# cat 1.1test
#!/bin/bash
total=$[ ${10} + ${11} ]
echo the tenth param is ${10}
echo the eleventh param is ${11}
echo the total is $total
[root@wzp ~]# ./1.1test 1 2 3 4 5 6 7 8 9 10 11
the tenth param is 10
the eleventh param is 11
the total is 21
对于这样的结果很好理解,只要注意下{10+}这个东东就行了!
1.2、读取程序名称
一开始我就在上面提到程序名称用$0即可表示,Ok,先看个例子:
[root@wzp
~]# chmod u+x 1.2test
[root@wzp ~]# cat 1.2test
#!/bin/bash
echo the name of the program is:$0
[root@wzp ~]# ./1.2test
the name of the program is:./1.2test
[root@wzp ~]# /root/1.2test
the name of the program is:/root/1.2test
很明显,得出的结果不是我们要的,我们只要输出1.2test这个结果。它所传递的变量$0的字符串是程序的完整路径,而不是名称,这里我们可以通过basename命令实现只返回程序名称,把脚本修改成如下:
[root@wzp
~]# cat 1.2test
#!/bin/bash
name=`basename $0`
echo the name of the program is:$name
[root@wzp ~]# ./1.2test
the name of the program is:1.2test
[root@wzp ~]# $HOME/1.2test
the name of the program is:1.2test
呵呵,这下通过basename实现我们要的结果,有点注意的是使用反单引号来给name赋值,否则命令无法生效!
通过基于使用脚本的名称可以实现执行不同功能,下面看个例子:
[root@wzp
~]# cp 1.2test 51cto
[root@wzp ~]# ln -s 1.2test netease
[root@wzp ~]# ls -l 1.2test 51cto netease
-rwxr--r-- 1 root root 179 02-13 11:21 1.2test
-rwxr--r-- 1 root root 179 02-13 11:22 51cto
lrwxrwxrwx 1 root root 7 02-13
11:22 netease -> 1.2test
[root@wzp ~]# cat 1.2test
#!/bin/bash
name=`basename $0`
if [ $name = "51cto" ]
then
echo $name is a great IT community
elif [ $name = "netease" ]
then
echo $name is a great internet-sp
corparation
fi
[root@wzp ~]# ./51cto
51cto is a great IT community
[root@wzp ~]# ./netease
netease is a great internet-sp corparation
上面的例子通过脚本名称实现了不同内容的输出,可知basename好用啦!
脚本是先判断basename,然后根据basename执行函数。
1.3、测试参数
在shell脚本中使用命令行参数要小心,如果执行脚本缺少必要的参数,则会出现报错信息,如下:
[root@wzp
~]# cat 1.1test
#!/bin/bash
total=$[ ${10} + ${11} ]
echo the tenth param is ${10}
echo the elevnth param is ${11}
echo the total is $total
[root@wzp ~]# ./1.1test
./1.1test: line 2: + : syntax error: operand
expected (error token is " ")
the tenth param is
the elevnth param is
the total is
我们不输入任何命令行参数,则脚本无法执行。
所以,我们可以通过-n这个参数进行检测:
[root@wzp
~]# cat 1.2test
#!/bin/bash
if [ -n "$1" ]
then
echo $1 exists !
else
echo your inputting is wrong
fi
[root@wzp ~]# ./1.2test twentyfour
twentyfour exists !
[root@wzp ~]# ./1.2test
your inputting is wrong
由此可见,通过该方法是检测参数是否存在的好方法。
2、特殊的参数变量
在bash shell中有一些特殊的变量用户跟踪命令行参数。
2.1、参数计数
我们可以使用bash shell提供的特殊变量$#来检测执行脚本时所包含的命令行参数的个数,看如下例子:
[root@wzp ~]# cat 2.1test
#!/bin/bash
echo there were $# parameters supplied.
[root@wzp ~]# chmod u+x 2.1test
[root@wzp ~]# ./2.1test
there were 0 parameters supplied.
[root@wzp ~]# ./2.1test aa bb cc
there were 3 parameters supplied.
所以,$#是一个值得我们记住脑中的好变量!
2.2、获取所有参数
有时候需要获取命令行中的参数,并对它们进行迭代。这里主要通过两个变量来实现对命令行参数的迭代,分别是:
变量$*和变量$@
变量$*将所有参数视为一个单词
变量$@将分别对待每个参数
我们看个例子\(≧▽≦)/
[root@wzp
~]# chmod u+x 2.2test
[root@wzp ~]# cat 2.2test
#!/bin/bash
a=1
for param1 in "$*"
do
echo "\$* parameter #$a = $param1"
a=$[ $a+1 ]
done
b=1
for param2 in "$@"
do
echo "\$# parameter #$b = $param2"
b=$[ $b+1 ]
done
c=1
for param3 in "$#"
do
echo "the total counts = $param3"
c=$[ $c+1 ]
done
[root@wzp ~]# ./2.2test a b c d e f
$* parameter #1 = a b c d e f
$# parameter #1 = a
$# parameter #2 = b
$# parameter #3 = c
$# parameter #4 = d
$# parameter #5 = e
$# parameter #6 = f
the total counts = 6
通过一个for循环迭代特殊变量,充分体现出$*$@$#三个特殊变量用途!
3、移位
bash shell提供了一个工具叫shift命令,实现改变命令行参数的相对位置
默认将每个参数变量左移一位。即为,$3的值移动给变量$2($n+1->$n),而变量$1则被丢弃,当然,$0这个程序名称没变。下面看个例子:
[root@wzp ~]# cat 3test
#!/bin/bash
count=1
while [ -n "$1" ]
do
echo "parameter #$count = $1"
count=$[ $count + 1 ]
shift
done
[root@wzp ~]# chmod u+x 3test
[root@wzp ~]# ./3test 51cto emc linux rac
parameter #1 = 51cto
parameter #2 = emc
parameter #3 = linux
parameter #4 = rac
每测试一个参数,使用shift命令将参数移前一位,所以通过while循环即可是的每个参数都变成$1被循环下去显示出来。当然,我们可以指定shift的位数,而不是默认的一位。看如下例子:
[root@wzp
~]# cat 3test
#!/bin/bash
echo "the original parameter : $*"
shift 3
echo "the new shift parameter is : $1"
[root@wzp ~]# ./3test aa bb cc dd ee
the original parameter : aa bb cc dd ee
the new shift parameter is : dd
指定位数为3后,aa bb cc则被忽略了,直接把dd当成$1.
4、处理选项
选项是有破折号引导的单个字母,它更改命令的行为。如下罗列一些标准化选项:
**********************************************
选项
描述
-a
实现所有对象
-c
生成计数
-d
指定目录
-e
展开对象
-f
指定读取数据的文件
-h
显示命令的帮助信息
-i
忽略大小写
-l
生成长格式的输出
-n
使用非交互式(批量)模式
-o
指定一个输出文件来重定向输出
-q
以quite模式退出
-r
递归处理目录和文件
-s
以silent模式执行
-v
生成verbose模式
-x
排除和拒绝
-y
设置所有提问回答为yes
**********************************************
4.1、处理简单选项
先来看一个例子:
[root@wzp
~]# cat 4test
#!/bin/bash
while [ -n "$1" ]
do
case "$1" in
-a) echo "the -a option exists";;
-b) echo "the -b option exists";;
-c) echo "the -c option exists";;
*) echo "the '$1' is not an option ";;
esac
shift
done
[root@wzp ~]# ./4test -a -b -c -d -e
the -a option exists
the -b option exists
the -c option exists
the '-d' is not an option
the '-e' is not an option
通过case语句循环判断各个选项,并且通过shift灵活移动选项变量。
4.2、从参数中分离选项
执行shell脚本经常会遇到使用选项又需要使用参数的情况。在linux中的标准方式是通过特殊字符码(--,双破折号)将二者分开,表示说当这个脚本程序发现双破折号后,就自动把剩余的命令行视为参数,而不再是选项了,如下看个例子:
[root@wzp
~]# cat 4test
#!/bin/bash
while [ -n "$1" ]
do
case "$1" in
-a) echo "the -a option exists";;
-b) echo "the -b option exists";;
-c) echo "the -c option exists";;
--) shift
break;;
*) echo "the '$1' is not an option ";;
esac
shift
done
count=1
for param in $@
do
echo "parameter #$count:$param"
count=$[ $count + 1 ]
done
[root@wzp ~]# ./4test -a -c -f -- -b test
the -a option exists
the -c option exists
the '-f' is not an option
parameter #1:-b
parameter #2:test
如上先通过while循环,把满足条件的选项显示出来,不满足条件的选项也显示出,并说明 is not an option
,当使用--把剩下的被脚本识别为参数的命令行则通过break跳出循环,并且在shift作用下置位成$1,然后在for循环下逐一显示出来,表示现实出来的即为参数,而非选项!
如上的脚本得仔细分析,不然很容易出错。
如果不通过双破折号隔离,如下的结果也是我们想象之中的:
[root@wzp
~]# ./4test -a -c -f -b test
the -a option exists
the -c option exists
the '-f' is not an option
the -b option exists
the 'test' is not an option
完全是while循环的判断,没法跳出来执行for循环。
5、获取用户输入
有时在脚本执行过程中需要询问一个问题并等待执行脚本的人员应答,bash shell提供的read命令可以实现这一需求。
5.1、基本读取
read命令接受标准输入(键盘输入),如下示例:
[root@wzp ~]# chmod u+x 5.1test
[root@wzp ~]# cat 5.1test
#!/bin/bash
echo -n "please input your name:"
read name
echo "hello $name, welcome to IT website"
[root@wzp ~]# ./5.1test
please input your name:twentyfour
hello twentyfour, welcome to IT website
通过一个-n选项使得脚本执行输入不用换行显示。
如上通过echo显示结果,实际上可以直接通过read命令在-p选项下直接把输入的内容附加给后面指定的变量,如下例子,效果跟上面完全一样:
[root@wzp
~]# cat 5.1test
#!/bin/bash
read -p "please input your name:" name
echo "hello $name, welcome to IT website"
[root@wzp ~]# ./5.1test
please input your name:CCIE
hello CCIE, welcome to IT website
所以,我们更多可以采用这种方法。
如上的两个方法,我们都是把输入的值赋给了变量name,实际上我们可以不使用这个变量name。这么一来,read命令会把输入的命令赋给一个环境变量REPLY,先来看一个效果:
[root@wzp
~]# read
the content will be sent to \$REPLY
[root@wzp ~]# echo $REPLY
the content will be sent to $REPLY
我使用\把变量转义不被识别,在read命令下输入的内容将被缓存赋给环境变量$REPLY(这个是系统级别的,直接引用),这下再来看个例子:
[root@wzp
~]# cat 5.1test
#!/bin/bash
read -p "please input your name:"
echo "hello $REPLY, welcome to IT website"
[root@wzp ~]# ./5.1test
please input your name:IBM
hello IBM, welcome to IT website
很明显,这个例子跟如上的很接近,但是这个脚本没使用name变量,所以我输入的IBM被系统赋给了环境变量$REPLY。
5.2、计时
如上我们可以通过read命令实现交互性的操作,但是假如没有执行脚本的人员操作,脚本则无法自动运行下去。这个时候就可以使用-t选项指定一个计时器,表示等待时间段(单位为秒),如果超过指定的时间,read命令将返回一个非零退出状态,通过判断语句则使脚本可以自动跳过运行下去,我们先看一个例子:
[root@wzp
~]# chmod u+x 5.2test
[root@wzp ~]# cat 5.2test
#!/bin/bash
if read -t 5 -p "please input your name:"
then
echo "hello $REPLY, welcome to come back
here"
else
echo "sorry , you are too slow "
fi
[root@wzp ~]# ./5.2test
please input your name:twentyfour
hello twentyfour, welcome to come back here
[root@wzp ~]# ./5.2test
please input your name:sorry , you are too slow
如上通过-t
5是的输入超过5秒则跳到else的判断结果,有点需要注意就是-p必须放置在-t的后面,否则报错!如上我没有任何输入,超过5秒,则脚本返回了sorry
, you are too slow的内容。
到这里还有一个挺经典的-n选项不得不提,除了如上输入时间计时,read还可以通过添加-n选项计数输入的字符。等输入的字符达到预定数目时就自动退出,这里借助case看一个例子:
[root@wzp
~]# cat 5.2test
#!/bin/bash
read -n1 -p "do you want to continue [Y/N]?"
case $REPLY in
Y | y) echo
echo "fine ,continue on ..";;
N | n) echo
echo "OK, goodbye...";;
esac
[root@wzp ~]# ./5.2test
do you want to continue [Y/N]?y
fine ,continue on ..
[root@wzp ~]# ./5.2test
do you want to continue [Y/N]?N
OK, goodbye...
如上-n后面是数字1,表示read命令接收到一个字符就退出,所以输入Y/N后不用回车就马上执行下去了。这里出现了两个echo,主要是使得结果换行显示,更显人性化。还有就是通过|符号识别大小写,也是人性化。
5.3、默读
有时候需要脚本用户进行输入,但输入的数据不显示出来,比如像password的输入。这里可以借用read命令下的-s选项,使得输入的数据颜色跟背景颜色一致,实现不显示数据的效果,看如下例子:
[root@wzp
~]# cat 5.3test
#!/bin/bash
read -s -p "please input your passwd:"
echo your passwd is $REPLY
[root@wzp ~]# chmod u+x 5.3test
[root@wzp ~]# ./5.3test
please input your passwd:your passwd is aaa
[root@wzp ~]# ./5.3test
please input your passwd:your passwd is 51cto
哈哈,这不失为一个非常棒的选项。还有,别以为数据颜色跟背景颜色一样后,你可以通过数据把数据选上而显示出来,linux命令行下输入的数据不占位,压根无法让你选上!
5.4、读取文件
read命令可以读取linux系统上存储的文件数据,每调用一次read命令,都会去读取一行文本(注意,是一行,不是整个文件内容),当read命令读完的文本内容将以非零状态退出。借用while命令看一个例子:
[root@wzp
~]# cat 5.4test
#!/bin/bash
count=1
cat 51cto.test | while read line
do
echo "LINE $count : $line"
count=$[ $count + 1 ]
done
[root@wzp ~]# cat 51cto.test
aaaaaaaaaa
bbbbbbbbbb
cccccccccc
[root@wzp ~]# ./5.4test
LINE 1 : aaaaaaaaaa
LINE 2 : bbbbbbbbbb
LINE 3 : cccccccccc
这里的51cto.test跟脚本文件放置同一个目录,当然最后就把要读取的文件以绝对路径写入脚本防止脚本读取不到。while命令使用read不断循环读取文件51cto.test中每一行,然后显示出来,直到read读取完后以非零状态退出而结束!
bash shell笔记4 处理用…的更多相关文章
- bash shell笔记1 脚本基础知识
原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://twentyfour.blog.51cto.com/945260/505644 * ...
- bash shell笔记7 创建函数
原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://twentyfour.blog.51cto.com/945260/525126 知 ...
- bash shell笔记6 脚本控制
原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://twentyfour.blog.51cto.com/945260/522415 知 ...
- bash shell笔记5 显示数据
原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://twentyfour.blog.51cto.com/945260/521455 知 ...
- bash shell笔记3 结构化命令二
原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://twentyfour.blog.51cto.com/945260/513601 三 ...
- bash shell笔记2 结构化命令
二.使用结构化命令 知识内容: # 改变命令流 # 使用if-then逻辑 # 嵌套if-then # 测试条件 # 高级if-then功能 许多程序在脚本命令之间需要某些逻辑控制流,有些命令允许脚本 ...
- 单行bash、shell、perl命令
主题:单行经典bash.shell.perl命令 作者:luomg 摘要: 会陆陆续的写自己工作中的常用有意思的命令,争取你能看完后就能搞定常见操作, 且尽量自少提供基本shell.perl的实现方式 ...
- 什么是shell? bash和shell有什么关系?
什么是shell? bash和shell有什么关系? 博客分类: Linux 什么是Shell? shell是你(用户)和Linux(或者更准确的说,是你和Linux内核)之间的接口程序 ...
- bash和shell的关系
bash是borne again shell的缩写,它是shell的一种,Linux上默认采用的是bash. shell脚本中的方法带不带function的区别,例如: function foo () ...
随机推荐
- React 源码剖析系列 - 生命周期的管理艺术
目前,前端领域中 React 势头正盛,很少能够深入剖析内部实现机制和原理. 本系列文章 希望通过剖析 React 源码,理解其内部的实现原理,知其然更要知其所以然. 对于 React,其组件生命周期 ...
- H264的nalu type有哪些?
1.forbidden_bit: 禁止位,初始为0,当网络发现NAL单元有比特错误时可设置该比特为1,以便接收方纠错或丢掉该单元. 2.nal_ ...
- 机器学习算法实现解析——libFM之libFM的模型处理部分
本节主要介绍的是libFM源码分析的第三部分--libFM的模型处理. 3.1.libFM中FM模型的定义 libFM模型的定义过程中主要包括模型中参数的设置及其初始化,利用模型对样本进行预测.在li ...
- 为什么选择MpVue进行小程序的开发
前言 mpvue是一款使用Vue.js开发微信小程序的前端框架.使用此框架,开发者将得到完整的 Vue.js 开发体验,同时为H5和小程序提供了代码复用的能力.如果想将 H5 项目改造为小程序,或开发 ...
- 关于public static void main(String[] args)相关知识
main()方法是Java应用程序的入口方法,也就是说,程序在运行的时候,第一个执行的方法就是main()方法,这个方法和其他的方法有很大的不同.比如方法的名字必须是main,方法必须是public ...
- WCF Restful 服务 Get/Post请求
Restful Get方式请求: Restful服务 Get请求方式:http://localhost:10718/Service1.svc/Get/A/B/C http://localhost:1 ...
- [Luogu4169][Violet]天使玩偶/SJY摆棋子
luogu 题意 一个平面上有\(n\)个点,\(m\)次操作,每次新增一个点,或者是询问离某个点最近的点的距离.这里的距离是曼哈顿距离. \(n,m\le3*10^5\) sol 写一发\(CDQ\ ...
- yii2史上最简单式安装教程,没有之一(转)
测试说明:按照文章下载文件,虽然是tgz文件,用winrar解压,在CMD中运行init.bat文件. 既然是安装Yii,我们先去官网下载一份Yii的高级模版,什么,你说打开页面乱七八糟的英文字母你看 ...
- Python学习笔记之selenium 定制启动 chrome 的选项
在自动化中,默认情况下我们打开的就是一个普通的纯净的chrome浏览器,而我们平时在使用浏览器时,经常就添加一些插件,扩展,代理之类的应用.所以使用 selenium 时,我们可能需要对 chrome ...
- css学习笔记之图像
图像与文本的对齐方式: vertical-align:text-top;表示的意思是图像的顶部和同一行的文本对齐,但文本不会超出图片的上边线. vertical-align:middle;表示的意思是 ...