跟散仙学shell编程(四)

上篇介绍了for循环命令的使用,本篇的shell学习,我们来看下如何在shell环境下处理用户的输入,我们可以向运行的shell从外部传入一些参数,通常情况下
$0是程序名
$1是第一个参数
$2是第二个参数
依次类推知道第9个参数$9
第9个之后需要${10}以此,至无限的


[search@h1 812]$ cat a.sh


echo "你输入的第一个数是: $1"


[search@h1 812]$ sh a.sh 2
你输入的第一个数是: 2
[search@h1 812]$


[search@h1 812]$ cat a.sh 


echo "你输入的第1个数是: $1"
echo "你输入的第2个数是: $2"

echo "你输入的第3个数是: $3"


[search@h1 812]$ sh a.sh 4 5 898
你输入的第1个数是: 4
你输入的第2个数是: 5
你输入的第3个数是: 898
[search@h1 812]$


如果穿的是带空格的字符串,记得用双引号引起来即可。
多于10个参数的我们需要使用大括号来引用
[search@h1 812]$ cat aa.sh 


echo "第10个参数: $10"
echo "第11个参数: $11"


echo "第10个参数大括号: ${10}"


[search@h1 812]$ sh aa.sh 1 2 3 4 5 6 7 8 9 a 11 12
第10个参数: 10
第11个参数: 11
第10个参数大括号: a
[search@h1 812]$


$0可以获取程序名
[search@h1 812]$ cd
[search@h1 ~]$ sh 812/cc.sh
程序名是: 812/cc.sh
[search@h1 ~]$ cd 812/
[search@h1 812]$ chmod u+x cc.sh
[search@h1 812]$ ./cc.sh
程序名是: ./cc.sh
[search@h1 812]$


如果只想要程序名,而不用带路径的话,可以使用basename命令来获取
[search@h1 ~]$ cat  812/cc.sh 


echo "程序名是: $0"


name=`basename $0`


echo "我永远只显示程序名: $name"

date
[search@h1 ~]$ sh 812/cc.sh
程序名是: 812/cc.sh
我永远只显示程序名: cc.sh
2014年 08月 13日 星期三 03:54:57 CST
[search@h1 ~]$

我们可以通过-n来测试参数中是否有数据:
[search@h1 812]$ cat b.sh 


if [ -n "$1" ] ; then
echo "有数据: $1"
else

echo "对不起,请输入数据: $1"
fi

[search@h1 812]$ sh b.sh
对不起,请输入数据:
[search@h1 812]$ sh b.sh 你好
有数据: 你好
[search@h1 812]$


如何知道参数总个数呢? s#命令可以满足我们

[search@h1 812]$ cat bb.sh 


echo "你输入总个数: $#"
[search@h1 812]$ sh bb.sh 1 2 a b cc
你输入总个数: 5
[search@h1 812]$ sh bb.sh 1 2 a b
你输入总个数: 4
[search@h1 812]$ sh bb.sh
你输入总个数: 0
[search@h1 812]$

那么如何获取参数里面最后一个参数呢?
命令: ${!#}
[search@h1 812]$ cat bb.sh 


echo "最后一个参数是: ${!#} "
[search@h1 812]$ sh bb.sh
最后一个参数是: bb.sh
[search@h1 812]$ sh bb.sh 2 a z
最后一个参数是: z
[search@h1 812]$


如何获取所有的数据?
$*可以奖所有参数作为一个字符串显示出来
$@可以把所有参数当成一个数组来执行
[search@h1 812]$ cat d.sh 


echo "\$* 所有的: $*"
echo "\$@ 所有的: $@"


#两者的区别

for var in "$*"
do

echo "\$*的遍历是: $var"

done

echo "============================================="


for var in "$@"
do

echo "\$@的遍历是: $var"


done


[search@h1 812]$ sh d.sh 1 2 a b 100
$* 所有的: 1 2 a b 100
$@ 所有的: 1 2 a b 100
$*的遍历是: 1 2 a b 100
=============================================
$@的遍历是: 1
$@的遍历是: 2
$@的遍历是: a
$@的遍历是: b
$@的遍历是: 100
[search@h1 812]$


shift命令,可以来移位参数:

[search@h1 812]$ cat dd.sh 


echo "所有的参数是: $*"


shift 2


echo "移位后的参数是: $*"
[search@h1 812]$ sh dd.sh 1 3 9 00
所有的参数是: 1 3 9 00
移位后的参数是: 9 00
[search@h1 812]$

处理选项:
[search@h1 812]$ cat e.sh 


while [ -n "$1" ]

do


case "$1" in

-a) echo "find the -a option" ;;
-b) echo "find the -b option" ;;
-c) echo "find the -c option" ;;
*) echo "$1 is not an option" ;;

esac
shift

done





[search@h1 812]$ sh e.sh -a -b -c -d
find the -a option
find the -b option
find the -c option
-d is not an option
[search@h1 812]$ sh e.sh -a
find the -a option


上面程序,充分利用了移位技术,来保证每个参数只会被处理一遍。

如何使选项与参数分离呢,我们可以使用--命令来做个小程序测试:
[search@h1 812]$ cat s.sh 


while [ -n "$1" ]

do


case "$1" in
-a) echo "a exist";;
-b) echo "b exist";;
-c) echo "c exist";;
-d) echo "d exist";;
--) shift
break;;
*) echo "$1 is not an option"

esac

shift

done


for var in "$@"

do

echo "剩余的参数是: $var"


done



[search@h1 812]$ sh s.sh -a -b -e -- 1 2 3
a exist
b exist
-e is not an option
剩余的参数是: 1
剩余的参数是: 2
剩余的参数是: 3
[search@h1 812]$

下面看一个getopts命令,可以帮助我们处理选项与参数的关系:
$OPTARG 保存环境变量的值 $OPTID 保存了参数列表里面的位置
如果遇到了未知的参数,会以问号代替输出
[search@h1 812]$ cat g.sh 


while getopts :ab:c opt

do


case "$opt" in
a) echo "-a exist";;
b) echo "-b exist, with value $OPTARG";;
c) echo "-c exist";;
*) echo "unknow option $opt";;

esac

done
[search@h1 812]$ sh g.sh -ab test1 -d
-a exist
-b exist, with value test1
unknow option ?
[search@h1 812]$


下面我们来看下如何在shell里面获取用户输入,就像我们在JAVA中使用Scanner对象获取键盘输入一样:
read命令会从键盘读入或从一个文件描述符里面读入数据,然后放进一个变量里面
[search@h1 812]$ cat r.sh 


echo -n "请输入你的名字:"

read name

echo "Hello $name "
[search@h1 812]$ sh r.sh
请输入你的名字:jim
Hello jim
[search@h1 812]$ sh r.sh
请输入你的名字:dongliang
Hello dongliang
[search@h1 812]$


我们还可以直接使用-p命令读入一行数据:
[search@h1 812]$ cat n.sh 


read -p "请输入你的年龄:" age

echo "你的年龄是: $age"
[search@h1 812]$ sh n.sh
请输入你的年龄:23
你的年龄是: 23
[search@h1 812]$ sh n.sh
请输入你的年龄:100
你的年龄是: 100
[search@h1 812]$

你可以在read时不指定变量名,系统默认会放在$REPLY

[search@h1 812]$ cat m.sh 


read -p "input name: "

echo "你输入的是: $REPLY"
[search@h1 812]$ sh m.sh
input name: solr
你输入的是: solr
[search@h1 812]$


除此之外,我们还可以对输入,设置个超时时间,如果一段时间内没人输入,就结束等待状态,程序退出!

[search@h1 812]$ cat q.sh 


if read -t 5 -p "请在5秒内输入名字:" name
then
echo "你好 $name"
else


echo "对不起,你输入太慢了!"

fi
[search@h1 812]$ sh q.sh
请在5秒内输入名字:a
你好 a
[search@h1 812]$ sh q.sh
请在5秒内输入名字:对不起,你输入太慢了!
[search@h1 812]$


[search@h1 812]$ cat w.sh 


read -n1 -p "yes or no?" var

case $var in

Y | y) echo "contine...";;
N | n) echo "OK. bye bye"

exit ;;

esac

echo `date`

[search@h1 812]$ sh w.sh
yes or no?ycontine...
2014年 08月 13日 星期三 05:37:10 CST
[search@h1 812]$ sh w.sh
yes or no?nOK. bye bye
[search@h1 812]$ sh w.sh
yes or no?z2014年 08月 13日 星期三 05:37:20 CST
[search@h1 812]$


-n后面的数字1,代码可以接受几个字符,而不必按回车键

下面看下隐藏方式读取数据:
[search@h1 812]$ cat p.sh 


read -s -p "请输入密码: " pwwd


echo "你的密码是: $pwwd"
[search@h1 812]$ sh p.sh
请输入密码: 你的密码是: abc
[search@h1 812]$ sh p.sh
请输入密码: 你的密码是: hahahah
[search@h1 812]$

最后看下如何从一个文件里面按行读取数据:

[search@h1 812]$ cat ccc.sh 


cat abc.txt | while read line
do


echo "数据: $line"

done


echo `date`

[search@h1 812]$ sh ccc.sh
数据:
数据:
数据: a
数据: b
数据: cc
数据: dd the
数据: ee
2014年 08月 13日 星期三 05:45:23 CST
[search@h1 812]$ cat abc.txt


a
b
cc
dd the
ee
[search@h1 812]$
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值