shell 编程(四)

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

Java代码  
  1. [search@h1 812]$ cat a.sh   
  2.   
  3.   
  4.   
  5.   
  6. echo "你输入的第一个数是: $1"  
  7.   
  8.   
  9.   
  10. [search@h1 812]$ sh a.sh  2  
  11. 你输入的第一个数是: 2  
  12. [search@h1 812]$   

 

Java代码  
  1. [search@h1 812]$ cat a.sh   
  2.   
  3.   
  4.   
  5.   
  6. echo "你输入的第1个数是: $1"  
  7. echo "你输入的第2个数是: $2"  
  8.   
  9. echo "你输入的第3个数是: $3"  
  10.   
  11.   
  12. [search@h1 812]$ sh  a.sh  898  
  13. 你输入的第1个数是: 4  
  14. 你输入的第2个数是: 5  
  15. 你输入的第3个数是: 898  
  16. [search@h1 812]$   



如果穿的是带空格的字符串,记得用双引号引起来即可。 
多于10个参数的我们需要使用大括号来引用 

Java代码  
  1. [search@h1 812]$ cat aa.sh   
  2.   
  3.   
  4.   
  5.   
  6. echo "第10个参数:  $10"  
  7. echo "第11个参数:  $11"  
  8.   
  9.   
  10.   
  11.   
  12. echo "第10个参数大括号:  ${10}"  
  13.   
  14.   
  15.   
  16. [search@h1 812]$ sh aa.sh  9 a 11 12  
  17. 10个参数:  10  
  18. 11个参数:  11  
  19. 10个参数大括号:  a  
  20. [search@h1 812]$   



$0可以获取程序名 

Java代码  
  1. [search@h1 812]$ cd  
  2. [search@h1 ~]$ sh 812/cc.sh   
  3. 程序名是: 812/cc.sh  
  4. [search@h1 ~]$ cd 812/  
  5. [search@h1 812]$ chmod u+x cc.sh   
  6. [search@h1 812]$ ./cc.sh   
  7. 程序名是: ./cc.sh  
  8. [search@h1 812]$   



如果只想要程序名,而不用带路径的话,可以使用basename命令来获取 

Java代码  
  1. [search@h1 ~]$ cat  812/cc.sh   
  2.   
  3.   
  4.   
  5.   
  6. echo "程序名是: $0"  
  7.   
  8.   
  9.   
  10. name=`basename $0`  
  11.   
  12.   
  13. echo "我永远只显示程序名: $name"  
  14.   
  15. date  
  16. [search@h1 ~]$ sh 812/cc.sh     
  17. 程序名是: 812/cc.sh  
  18. 我永远只显示程序名: cc.sh  
  19. 2014年 08月 13日 星期三 03:54:57 CST  
  20. [search@h1 ~]$   


我们可以通过-n来测试参数中是否有数据: 

Java代码  
  1. [search@h1 812]$ cat b.sh   
  2.   
  3.   
  4.   
  5.   
  6. if [ -n "$1"  ] ; then  
  7. echo "有数据: $1"  
  8. else  
  9.   
  10. echo "对不起,请输入数据: $1"  
  11. fi  
  12.   
  13. [search@h1 812]$ sh b.sh   
  14. 对不起,请输入数据:   
  15. [search@h1 812]$ sh b.sh  你好  
  16. 有数据: 你好  
  17. [search@h1 812]$   



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

Java代码  
  1. [search@h1 812]$ cat bb.sh   
  2.   
  3.   
  4.   
  5.   
  6.   
  7. echo "你输入总个数:  $#"  
  8. [search@h1 812]$ sh bb.sh  2 a b cc  
  9. 你输入总个数:  5  
  10. [search@h1 812]$ sh bb.sh  2 a b   
  11. 你输入总个数:  4  
  12. [search@h1 812]$ sh bb.sh    
  13. 你输入总个数:  0  
  14. [search@h1 812]$   


那么如何获取参数里面最后一个参数呢? 
命令:  ${!#} 

Java代码  
  1. [search@h1 812]$ cat bb.sh   
  2.   
  3.   
  4.   
  5.   
  6.   
  7. echo "最后一个参数是: ${!#} "  
  8. [search@h1 812]$ sh bb.sh   
  9. 最后一个参数是: bb.sh   
  10. [search@h1 812]$ sh bb.sh  2 a z  
  11. 最后一个参数是: z   
  12. [search@h1 812]$   



如何获取所有的数据? 
$*可以奖所有参数作为一个字符串显示出来 
$@可以把所有参数当成一个数组来执行 

Java代码  
  1. [search@h1 812]$ cat d.sh   
  2.   
  3.   
  4.   
  5. echo "\$*  所有的:  $*"  
  6. echo "\$@  所有的:  $@"  
  7.   
  8.   
  9.   
  10. #两者的区别  
  11.   
  12. for var in "$*"  
  13. do  
  14.   
  15. echo  "\$*的遍历是: $var"  
  16.   
  17. done  
  18.   
  19. echo "============================================="  
  20.   
  21.   
  22.   
  23. for var in "$@"  
  24. do  
  25.   
  26. echo "\$@的遍历是:  $var"  
  27.   
  28.   
  29. done  
  30.   
  31.   
  32.   
  33.   
  34.   
  35.   
  36. [search@h1 812]$ sh d.sh  2 a b 100  
  37. $*  所有的:  2 a b 100  
  38. $@  所有的:  2 a b 100  
  39. $*的遍历是: 2 a b 100  
  40. =============================================  
  41. $@的遍历是:  1  
  42. $@的遍历是:  2  
  43. $@的遍历是:  a  
  44. $@的遍历是:  b  
  45. $@的遍历是:  100  
  46. [search@h1 812]$   



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

Java代码  
  1. [search@h1 812]$ cat dd.sh   
  2.   
  3.   
  4.   
  5. echo "所有的参数是:   $*"  
  6.   
  7.   
  8. shift 2   
  9.   
  10.   
  11. echo "移位后的参数是: $*"  
  12. [search@h1 812]$ sh dd.sh  00  
  13. 所有的参数是:   00  
  14. 移位后的参数是: 00  
  15. [search@h1 812]$   


处理选项: 

Java代码  
  1. [search@h1 812]$ cat e.sh   
  2.   
  3.   
  4.   
  5. while [  -n "$1"  ]  
  6.   
  7. do  
  8.   
  9.   
  10.   case "$1" in  
  11.     
  12.   -a) echo "find the -a option" ;;  
  13.   -b) echo "find the -b option" ;;  
  14.   -c) echo "find the -c option" ;;  
  15.    *) echo "$1 is not an option" ;;  
  16.     
  17.  esac  
  18. shift  
  19.   
  20. done  
  21.   
  22.   
  23.   
  24.   
  25.     
  26.   
  27.   
  28. [search@h1 812]$ sh e.sh  -a -b -c -d  
  29. find the -a option  
  30. find the -b option  
  31. find the -c option  
  32. -d is not an option  
  33. [search@h1 812]$ sh e.sh  -a  
  34. find the -a option  



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

如何使选项与参数分离呢,我们可以使用--命令来做个小程序测试: 

Java代码  
  1. [search@h1 812]$ cat s.sh   
  2.   
  3.   
  4.   
  5. while  [  -n "$1" ]  
  6.   
  7. do  
  8.   
  9.   
  10.    case "$1" in  
  11.      -a) echo "a exist";;  
  12.      -b) echo "b exist";;  
  13.      -c) echo "c exist";;  
  14.      -d) echo "d exist";;  
  15.      --) shift  
  16.          break;;  
  17.      *) echo "$1 is not an option"  
  18.   
  19. esac  
  20.   
  21. shift  
  22.   
  23. done  
  24.   
  25.   
  26.   
  27. for  var in "$@"  
  28.   
  29. do  
  30.   
  31.  echo "剩余的参数是:  $var"  
  32.   
  33.   
  34. done  
  35.   
  36.   
  37.   
  38.   
  39.   
  40.       
  41. [search@h1 812]$ sh s.sh  -a -b -e -- 3  
  42. a exist  
  43. b exist  
  44. -e is not an option  
  45. 剩余的参数是:  1  
  46. 剩余的参数是:  2  
  47. 剩余的参数是:  3  
  48. [search@h1 812]$   


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

Java代码  
  1. [search@h1 812]$ cat g.sh   
  2.   
  3.   
  4.   
  5.   
  6. while getopts :ab:c opt  
  7.   
  8. do   
  9.   
  10.   
  11.    case  "$opt" in  
  12.     a) echo "-a exist";;  
  13.     b) echo "-b exist,  with value $OPTARG";;  
  14.     c) echo "-c exist";;  
  15.     *) echo "unknow option  $opt";;  
  16.   
  17. esac  
  18.   
  19. done  
  20. [search@h1 812]$ sh g.sh -ab test1 -d  
  21. -a exist  
  22. -b exist,  with value test1  
  23. unknow option  ?  
  24. [search@h1 812]$   



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

Java代码  
  1. [search@h1 812]$ cat r.sh   
  2.   
  3.   
  4.   
  5. echo -n "请输入你的名字:"  
  6.   
  7. read name  
  8.   
  9. echo "Hello $name "  
  10. [search@h1 812]$ sh r.sh   
  11. 请输入你的名字:jim  
  12. Hello jim   
  13. [search@h1 812]$ sh r.sh   
  14. 请输入你的名字:dongliang  
  15. Hello dongliang   
  16. [search@h1 812]$  



我们还可以直接使用-p命令读入一行数据: 

Java代码  
  1. [search@h1 812]$ cat n.sh   
  2.   
  3.   
  4.   
  5.   
  6. read -p "请输入你的年龄:" age  
  7.   
  8. echo "你的年龄是: $age"  
  9. [search@h1 812]$ sh n.sh   
  10. 请输入你的年龄:23  
  11. 你的年龄是: 23  
  12. [search@h1 812]$ sh n.sh   
  13. 请输入你的年龄:100  
  14. 你的年龄是: 100  
  15. [search@h1 812]$   


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

Java代码  
  1. [search@h1 812]$ cat m.sh   
  2.   
  3.   
  4.   
  5. read -p "input name: "  
  6.   
  7. echo "你输入的是: $REPLY"  
  8. [search@h1 812]$ sh m.sh   
  9. input name: solr     
  10. 你输入的是: solr  
  11. [search@h1 812]$   



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

Java代码  
  1. [search@h1 812]$ cat q.sh   
  2.   
  3.   
  4. if read -t 5 -p "请在5秒内输入名字:" name  
  5. then  
  6. echo "你好 $name"  
  7. else  
  8.   
  9.   
  10. echo  "对不起,你输入太慢了!"  
  11.   
  12. fi  
  13. [search@h1 812]$ sh q.sh   
  14. 请在5秒内输入名字:a  
  15. 你好 a  
  16. [search@h1 812]$ sh q.sh   
  17. 请在5秒内输入名字:对不起,你输入太慢了!  
  18. [search@h1 812]$   



Java代码  
  1. [search@h1 812]$ cat w.sh   
  2.   
  3.   
  4.   
  5. read -n1 -p "yes or no?" var  
  6.   
  7. case $var in  
  8.   
  9.  Y | y) echo "contine...";;  
  10.  N | n) echo "OK. bye bye"     
  11.   
  12.     exit ;;  
  13.   
  14. esac  
  15.   
  16. echo `date`  
  17.   
  18. [search@h1 812]$ sh w.sh   
  19. yes or no?ycontine...  
  20. 2014年 08月 13日 星期三 05:37:10 CST  
  21. [search@h1 812]$ sh w.sh   
  22. yes or no?nOK. bye bye  
  23. [search@h1 812]$ sh w.sh   
  24. yes or no?z2014年 08月 13日 星期三 05:37:20 CST  
  25. [search@h1 812]$   



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

下面看下隐藏方式读取数据: 

Java代码  
  1. [search@h1 812]$ cat p.sh   
  2.   
  3.   
  4.   
  5. read -s -p "请输入密码: " pwwd  
  6.   
  7.   
  8. echo "你的密码是: $pwwd"  
  9. [search@h1 812]$ sh p.sh   
  10. 请输入密码: 你的密码是: abc  
  11. [search@h1 812]$ sh p.sh   
  12. 请输入密码: 你的密码是: hahahah  
  13. [search@h1 812]$   


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

Java代码  
    1. [search@h1 812]$ cat ccc.sh   
    2.   
    3.   
    4.   
    5. cat abc.txt | while read line  
    6. do  
    7.   
    8.   
    9. echo "数据: $line"  
    10.   
    11. done  
    12.   
    13.   
    14.   
    15.   
    16.   
    17.   
    18. echo `date`  
    19.   
    20. [search@h1 812]$ sh ccc.sh   
    21. 数据:   
    22. 数据:   
    23. 数据: a  
    24. 数据: b  
    25. 数据: cc  
    26. 数据: dd the  
    27. 数据: ee  
    28. 2014年 08月 13日 星期三 05:45:23 CST  
    29. [search@h1 812]$ cat abc.txt   
    30.   
    31.   
    32. a  
    33. b  
    34. cc  
    35. dd the   
    36. ee  
    37. [search@h1 812]$   

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。