Shell Notes(3)

> 算术赋值 与 算术扩展

算术扩展:$((expression)) 用它给表达式赋值,并用得到的结果来取来$((expression))。用来显示表达式的值或把值赋给一个变量

算术赋值:let “expression” 或 ((expression)) 用来给表达式赋值,并返回一个状态码。用来进行逻辑比较或赋值运算

# 算术扩展可以看做是类似 int 型返回值的函数,而算术赋值是类似 void 型的,无返回值,但是有返回的状态信息

let “expression” 在一行内可以给多个变量赋值,表达式空格隔开

而((expression)) 用“,”将多个表达式隔开

eg. 1到100中3的倍数的数字之和:

$((expression))

image

let “expression”

image

((expression))

image

> 特殊符号

1) ` `

键盘tab上方,数字1左侧

我觉得就是个隔离容器,在` `中间执行一条shell指令,` `之外可以使用其返回结果

如前面的例子,seq 1 100,返回的是1到100的顺序序列,for var in `seq 1 100`,则是为var提供了一个遍历的空间,应该是先执行了seq 1 100,然后通过` `将结果返回,提供给for循环

2) [ ]

像if,while等都用到,我觉得是一个条件判断容器,[ ] 会将其中间内容条件判断结果返回。

如前面的例子,在$((expression))中,$(())本身值返回值,不返回状态,故需要借用[]进行条件判断

而let 和(())都是有状态返回的,故不再需要[]

 

> 逻辑表达式

_[[_expression_]]_ # _ 意为空格

与:&& 或:||   大于:>   小于: <  等于:=

也可用 –gt –ge –lt –le –eq –ne

要说下的是字符串的比较,“=”支持模式匹配 [[ string=pattern ]],左侧是字符串,右侧是模式串

 

> 字符串模式匹配

${varname op pattern}

op可用的有

-------------------------------------------------

|   #       |  去除最小匹配前缀                 |

|   ##     |  去除最大匹配前缀                 |

|   %      |  去除最小匹配后缀                 |

|   %%   |  去除最大匹配后缀                 |

-------------------------------------------------

这些操作符一般用来操作路径名,以便提取或者移除某些组件,或者用来改变后缀。如下面的例子:

image

结果:

image

 

> 逻辑运算符

&& 和 ||

要说的是逻辑运算符的 lazy 特性。&& 和 || 都是二元,在计算时,如果仅通过左值就可以得到整个表达式的结果,就不再计算右值

如果 var1 || var2, 如果var1为true,则不再计算var2。想想,命令执行成功,则返回0,否则非零,此处,可借助&&的lazy特性,有条件地执行命令。

rm file1 || echo "delete file1 failed"

image

这里理解的时候有一个点要意识下:返回0,表示执行成功,成功为True,布尔运算,用的是True,不是返回值0;同理,返回值非零,表示不成功,为False

 

实例:

1、写一个脚本makepath,给出一个路径名,然后根据路径名,依次创建多级目录,如:makepath a/b/c/d,依次创建出目录a,a/b,a/b/c,a/b/c/d

image

使用了局部变量path,避免了在递归过程成,共享变量造成意外。

 

2、一个多项选择考试的小程序。该程序从一个数据文件中读入问题,显示这些问题给用户,程序能辨别正确选项的编号和错误选项的编号。用户可以随时提交答案并计算得分,然后退出程序

   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

# 照着书上拍的代码,信息量好大,等下细细研究下

 

3、查找系统中所有大于500M的文件,并把这些文件名写到一个文本文件中 并统计其个数

a) 查找大于500M的文件: find –size +500000000c –type f

b) 文件名写入到文本文件: find –size +500000000c –type f > files.dat 或者 find –size +500000000c –type f | tee files.dat 区别在于tee会在重定向输出的同时,在屏幕上同步显示输出内容

c) 统计文件个数:使用wc,每个文件名一行,故 wc –l

posted @ 2012-08-29 13:38  郝玉琨  阅读(347)  评论(0编辑  收藏  举报