Shell Notes(4)

闲话几句:不是特别喜欢按部就班地跟着教科书学东西,觉得刚开始一点都不了解的时候,需要看一点书,了解一些之后,就要多看实际的例子,通过实践、例子来把东西学明白。

接着前面(3)中的quiz的例子,把其中拍代码时不时很明白的几个点,抠出来琢磨下。

   1: #!/bin/bash
   2: # a quiz program
   3:  
   4: set -o xtrace
   5:  
   6: #============================
   7: function initialize ()
   8: {
   9: trap 'summarize ; exit 0' INT
  10: num_ques=0
  11: num_correct=0
  12: first_time=true
  13: cd ${QUIZDIR=./quiz} || exit 2
  14: }
  15:  
  16: #===========================
  17: function choose_subj ()
  18: {
  19: subjects=($(ls))
  20: PS3="Choose a subject for the quiz from the proceding list:"
  21: select Subject in ${subjects[*]};do
  22:     if [[ -z "$Subject" ]];then
  23:         echo "No subject chosen. Bye." >&2
  24:         exit 1
  25:     fi
  26:     echo $Subject
  27:     return 0
  28: done
  29: }
  30:  
  31: #===========================
  32: function exchange ()
  33: {
  34: temp_value=${questions[$1]}
  35: questions[$1]=${questions[$2]}
  36: questions[$2]=$temp_value
  37: }
  38:  
  39: #===========================
  40: function scramble ()
  41: {
  42: typeset -i index quescount
  43: questions=($(ls))
  44: questcount=${#questions[*]}
  45: ((index=questcount-1))
  46: while [[ $index -gt 0 ]];do
  47:     ((target=RANDOM%index))
  48:     exchange $target $index
  49:     ((index -= 1))
  50: done
  51: }
  52:  
  53: #===========================
  54: function ask ()
  55: {
  56: exec 3<$1
  57: read -u3 ques || exit 2
  58: read -u3 num_opts || exit 2
  59:  
  60: index=0
  61: choices=()
  62: while (( index < num_opts )) ; do
  63:     read -u3 next_choice || exit 2
  64:     choices=("${choices[@]}" "$next_choice")
  65:     ((index+=1))
  66: done
  67: read -u3 correct_answer || exit 2
  68: exec 3<&-
  69:  
  70: if [[ $first_time = true ]];then
  71:     first_time=false
  72:     echo -e "You may process the interrupt key at any time to quit.\n"
  73: fi
  74:  
  75: PS3=$ques" "
  76:  
  77: select answer in "${choices[@]}";do
  78:     if [[ -z "$answer" ]];then
  79:         echo "Not a valid choice. Please choose again"
  80:     elif [[ "$answer" = "$correct_answer" ]];then
  81:         echo "Correct!"
  82:         return 1
  83:     else
  84:         echo "No, the answer is $correct_answer."
  85:         return 0
  86:     fi
  87: done
  88: }
  89:  
  90: #================================
  91: function summarize ()
  92: {
  93: echo
  94: if (( num_ques == 0));then
  95:     echo "You did not answer any questions"
  96:     exit 0
  97: fi
  98:  
  99: (( percent=num_correct*100/num_ques ))
 100: echo "You answered $num_correct questions correctly, out of \
 101: $num_ques total questions."
 102: echo "Your score is $percent percent."
 103: }
 104:  
 105: #=================================
 106: # Main program
 107: initialize
 108:  
 109: subject=$(choose_subj)
 110: [[ $? -eq 0 ]] || exit 2
 111:  
 112: cd $subject || exit 2
 113: echo 
 114: scramble
 115:  
 116: for ques in ${questions[*]};do
 117:     ask $ques
 118:     result=$?
 119:     (( num_ques=num_ques+1 ))
 120:     if [[ $result == 1 ]];then
 121:         ((num_correct+=1))
 122:     fi
 123:     echo
 124:     sleep ${QUIZDELAY:=1}
 125: done
 126:  
 127: summarize
 128: exit 0
 129:  
 130: set +o xtrace

a) cd ${QUIZDIR:=./quiz} || exit 2

这里对QUIZDIR赋值,:= 表示给变量赋默认值

这里展开说,是shell对未赋值变量的值的处理方式:A,变量使用默认值 B,使用默认值并将其赋给变量 C,显示错误

> ":-" 使用默认值

:- 使用一个默认的值来代替空的没有赋值的变量,不能改变变量本来的值,只是在这句话执行的时候,让变量使用这个默认值

${name:-default} 如果name为空或没有赋值,就使用扩展值default,并把扩展值替换name的内容;否则使用name的内容

> ":=" 赋默认值

与":-"比较地看,:= 改变了变量的默认值。

${name:=default}

> :? 显示错误信息

当通过设置默认的变量值并不能给脚本中某些变量提供一个合理的值,如果变量为空或未赋值,:? 会显示出错误信息并中止脚本的执行,同时返回退出码 1

${name:? message}

如果message中包含空格,则要用""括起来

${var:?"variable not set!"}

另外:

" : " 冒号通常给命令行上其后的符号赋值而不会执行后面的命令,如果没有没有,shell会赋值并试图执行来自赋值语句的命令

eg.   : ${TEMPDIR:=/tmp}

b) subjects=($(ls))

从执行结果来说,这条命令是 先执行ls,然后将ls的结果作为一个数组,赋值给subjects

c) select Subject in ${subjects[*]};

利用select选择器,遍历subjects数组中的内容,subjects[index]返回对应数组中对应index的值,如果index为*,则返回整个数组

d) temp_value=${questions[$1]} ; questions[$1]=${questions[$2]} ; questions[$2]=$temp_value

常见的swap函数,要说的是对函数传入参数的使用,传入两个参数,直接用$1,$2引用即可

e) questcount=${#questions[*]}

前面${subjects[*]}得到一个数组,这里在数组名前面加#,得到是整个数组的大小。

f) exec 3<$1 ; read -u3 ques || exit 2

这里可以看到输入重定向后,使用重定向的文件描述符读取内容的方法 read后加选项 –u3

g) choices=("${choices[@]}" "$next_choice")

这条放在while循环语句里面,不断向数组中增加内容。

这里说的是${arrName[*]} 与${arrName[@]}的区别

在没有""包围的情况下,两者都是一样的,返回整个数组中的元素

在有""包围的情况下,"${arrName[*]}"将所有元素,作为一个元素来返回,如"a,b,c,d",而"${arrName[@]}",将元素独立返回,即返回的是一个数组,如"a","b","c","d"

---------------------写到这里,发现前面有些点,前天刚刚看过,55555,温故而知新啊-------------------

> grep

(global regular expression print) 在一个或多个文件中搜索是否包含某给定字符串,列出搜索结果所在的行

grep [options] pattern [file-list] pattern可以是简单的字符串,也可以是正则表达式

[options]

1、主选项

-E

将pattern解释为可扩展的正则表达式,功能同egrep

-F

将pattern解释为固定的正则表达式,功能同fgrep

-G

将pattern解释为基本的正则表达式,默认选项

2、其他选项

-c                       返回匹配行个数

-C n                   对每个匹配,显示n行上下文

-f patternfile    读取patternfile,文件中每行都是一个pattern,从输入中查找匹配每个模式的行

-h                       搜索多个文件时,隐藏每行开始的文件名

-I(大写i)             模式中的小写字母可以匹配大写字母,忽略大小写

-l(小写L)            仅显示匹配的文件名,每个文件名只显示一次

-m n                   设定最大显示行数n,即对所有匹配,只显示n行,之后的不再显示

-n                       在匹配结果前显示行号

-q                       不发送任何内容,只显示退出码

-r                        递归地扫描目录下的文件,此时file-list中含目录

-s                       静默,如果file-list中文件不存在或不可读,不显示错误信息

-v                       反向匹配,显示所有不匹配的行

-w                      全字匹配,模式必须与整个字匹配

-x                       整行匹配,模式必须匹配整行

grep 匹配成功,退出状态为0;没找到,状态为1;文件不可读或语法错误,状态为2

pattern 可以用单引号 '' 括起来,以防模式串中出现特殊字符

eg.

创建文件夹shfiles,如果创建成功,就将当前目录下所有扩展名为sh的文件拷贝到shfiles目录下:

(mkdir shfiles) && (cp `ls|grep '.sh$'` shfiles)

image

 

>test

这里主要是总结下tes计算表达式值的时候用到的一些选项:

Options:

-n string                string长度大于零则为true

-z string                string长度等于零则为true

string1=string2    两串相等为true

string1!=string2   两串不等为true

-d filename           filename是否为目录

-e filename           filename是否存在

-f filename            filename是否为普通文件

-r filename            filename是否可读

-s filename            filename存在且包含信息

-w filename           filename是否可写

-x filename            filename是否可执行

-a                            AND

-o                            OR

posted @ 2012-08-30 17:43  郝玉琨  阅读(343)  评论(0编辑  收藏  举报