Chinaunix首页 | 论坛 | 博客
  • 博客访问: 906503
  • 博文数量: 75
  • 博客积分: 1216
  • 博客等级: 少尉
  • 技术积分: 1998
  • 用 户 组: 普通用户
  • 注册时间: 2012-08-11 16:20
个人简介

优秀是一种习惯

文章分类

全部博文(75)

文章存档

2014年(1)

2013年(29)

2012年(45)

分类: Python/Ruby

2012-09-14 19:31:01

今天在shell脚本中,发现case语句的一个问题。就是指定小写字母[a-z]和大写字母[A-Z]的这种方法不管用用了出现如下情况:

  1. [root@station1 ~]# cat case.sh
  2. #!/bin/bash
  3. while :
  4. do
  5.     echo -n "input a letter: "
  6.     read var
  7.     case "$var" in
  8.       [a-z]) echo "Lowercase letter";;
  9.       [A-Z]) echo "Uppercase letter";;
  10.      [0-9]) echo "Digit";;
  11.       *) echo "Punctuation, whitespace, or other";;
  12. esac
  13. done
  14. [root@station1 ~]# bash case.sh
  15. input a letter: a
  16. Lowercase letter
  17. input a letter: A
  18. Lowercase letter
  19. input a letter: 2
  20. Digit
  21. input a letter: 0
  22. Digit
  23. input a letter: B
  24. Lowercase letter
  25. input a letter: y
  26. Lowercase letter
  27. input a letter: ^C
  28. [root@station1 ~]#

可以看到当输入大小写字母都会输出“Lowercase letter”

就当我疑惑不解的时候,奇迹发生了。。。。

  1. [root@station1 ~]# bash case.sh
  2. input a letter: Z
  3. Uppercase letter
  4. input a letter:

当输入大写Z的时候,终于出现了我们想要的结果:Uppercase letter
后来在man bash文档中也没有关于"-"代表范围的说明,值说想匹配"-",就把"-"放到[]中最前面或者最后面。


  1. case word in [ [(] pattern [ | pattern ] ... ) list ;; ] ... esac
  2. A case command first expands word, and tries to match it against each pattern in turn, using the same matching rules as for pathname
  3. expansion (see Pathname Expansion below). The word is expanded using tilde expansion, parameter and variable expansion, arithmetic sub-
  4. stitution, command substitution, process substitution and quote removal. Each pattern examined is expanded using tilde expansion, param-
  5. eter and variable expansion, arithmetic substitution, command substitution, and process substitution. If the shell option nocasematch is
  6. enabled, the match is performed without regard to the case of alphabetic characters. When a match is found, the corresponding list is
  7. executed. If the ;; operator is used, no subsequent matches are attempted after the first pattern match. Using ;& in place of ;; causes
  8. execution to continue with the list associated with the next set of patterns. Using ;;& in place of ;; causes the shell to test the next
  9. pattern list in the statement, if any, and execute any associated list on a successful match. The exit status is zero if no pattern
  10. matches. Otherwise, it is the exit status of the last command executed in list.

看下下面这个代码:

点击(此处)折叠或打开

  1. [root@station1 ~]# cat case.sh
  2. #!/bin/bash
  3. while :
  4. do
  5. echo -n "input a letter: "
  6. read var
  7. case "$var" in
  8. [a-c]) echo "Lowercase letter";;
  9. [A-Z]) echo "Uppercase letter";;
  10. [0-9]) echo "Digit";;
  11. *) echo "Punctuation, whitespace, or other";;
  12. esac
  13. done
  14. [root@station1 ~]# bash case.sh
  15. input a letter: a
  16. Lowercase letter
  17. input a letter: b
  18. Lowercase letter
  19. input a letter: c
  20. Lowercase letter
  21. input a letter: d
  22. Uppercase letter
  23. input a letter: e
  24. Uppercase letter
  25. input a letter: ^C
  26. [root@station1 ~]#

可以看出来它的编码方式是:aAbBcCdDeE...yYzZ
所以才会出现这种情况。这也算是一个小bug吧,如果想真的想达到我们想要的结果,可以用posix的[:upper:]。
个人想法:有时候出现这种情况也不是个坏事,或许还可以利用这个bug去做点事。。。。

阅读(3842) | 评论(2) | 转发(2) |
给主人留下些什么吧!~~

铁钉2012-09-17 23:11:30

#!/bin/bash   改为

#!/bin/sh   就不会有此Bug 了,我一般写 shell 都用这个

鸟哥のlinux2012-09-17 11:04:27

学习了