1、描述shell程序的运行原理(可附带必要的图形说明);
    shell是操作系统的外壳,为用户提供使用操作系统的接口,是命令语言、命令解释程序及程序设计语言的统称;是用户和Linux内核之间的接口程序,如果把Linux内核想象成一个球体的中心,shell就是围绕内核的外层,当从shell或其他程序向Linux传递命令时,内核会做出相应的反应。shell是一个命令语言解释器,它拥有自己内建的shell命令集,shell也能被系统中其他应用程序所调用。用户在提示符下输入的命令都由shell先解释然后传给Linux核心。如图:

2、总结shell编程中所涉及到的所有知识点;
变量:为程序在运行时在内存中申请的空间名字
bash环境,可分为以下变量:
本地变量:其作用域只在当前shell进程;
环境变量:其作用域为当前shell进程及其子进程;
局部变量:某个函数上下文,只存在于某个函数执行过程;
位置参数变量:在脚本中引用传递给脚本的参数;在函数中引用传递给函数的参数;
特殊变量:bash内建的用于保存某些特殊的值的相关变量,如:$?,$*,$@,$#等;
变量类型:
数值和字符类型
变量类型的作用:决定存储空间,运算,定义存储格式
语言对变量类型的支持力度:
强类型:严格区分变量类型,变量在使用前必须先声明变量类型,如C等
弱类型:不严格区分变量类型,一般变量有默认的类型,如bash,默认变量类型为字符型
本地变量:变量名只能包含数字、字母和下划线;且不能以数字开头;
引用变量:$name,${name}
强引用:‘’
弱引用:“”
命令引用:`COMMAND`,$(COMMAND)
声明:declare,let
查看所有变量:set
生命周期:创建到销毁
自动销毁:shell进程终止
手动销毁:unset name
环境变量:
被导出的本地变量:export name[=value]
declare -x name[=value]
查看所有的环境变量:env,printenv,export
销毁:unset name
脚本:实际上是运行一个bash进程,此进程负责从脚本文件中读取一个执行逻辑,而后由bash进程负责解析并运行此逻辑;
启动脚本:
(1)# bash 脚本文件位置
(2)#./脚本文件,通过脚本文件第一行的shebang来确定解释器路径如:#!/bin/bash
bash的常用选项:-n:解析脚本中的语法错误;-x:调试执行脚本
命令状态结果:
bash进程用于追踪执行的命令成功与否的状态:
$?:上一条命令的执行状态结果,0为成功,1-255表示失败
自定义脚本的状态结果:exit [n],在脚本中任何位置执行了exit命令即会终止当前shell进程
    条件测试:界定程序执行环境    
         整数测试:隐含着做数值大小比较,所以不要给变量引用加引用;
         $A -gt $B:是否大于;是则为“真”,否则为“假”;
         $A -ge $B: 是否大于等于;
         $A -lt $B:是否小于;
         $A -le $B: 是否小于等于;
         $A -eq $B: 是否等于;
         $A -ne $B:是否不等于;
     字符串测试:ASCII数值越大,字符比较时其值越大;
        "$A" > "$B":是否大于;
        "$A" < "$B":是否小于;
        "$A" == "$B":是否等于;
        "$A" != "$B":是否不等于;
        -z "$A":是否为空;空则为“真”,否则为“假”
        -n "$A":是否不空;不空则“真”,空则为“假”
     文件测试:测试文件的存在性以及属性;
        -e $file: 是否存在;存在则为“真”,否则为“假”;
        -a $file: 同上;
        -f $file:文件是否存在且为普通文件;
        -d $file:文件是否存在且为目录;
        -h $file:是否存在且为符号链接文件;
        -L $file: 同上
        -b $file:是否存在且为块设备文件;
        -c $file:是否存在且为字符设备文件;
        -S $file:是否存在且为套接字文件;
        -p $file: 是否存在且为管道文件;
        -r $file: 当前用户对文件是否拥有读权限;
       -w $file:当前用户对文件是否拥有写权限;
       -x $file:当前用户对文件是否拥有执行权限;
       -u $file:文件是否拥有SUID权限;
       -g $file:文件是否拥有SGID权限;
       -k $file:文件是否拥有sticky权限;
       -O $file: 当前用户是否为指定文件的属主;
       -G $file: 当前用户是否为指定文件的属组;
       双目操作符:
            $file1 -nt $file2: file1是否新于file2, file1的最近一次的修改时间戳是否晚于file2的;
            $file1 -ot $file2: file1是否旧于file2, file1的最近一次的修改时间戳是否早于file2的; 
            $file1 -ef $file2:file1与file2是否指向了同一个inode;测试二者是否为同一个文件的硬链接;
       特殊设备:
            /dev/null: bit buckets,接受所有的输入数据,并直接丢弃;/dev/zero:吐出一堆0
条件判断
            if CONDITION; then
                if-true-分支
           else
                if-false-分支
            fi
! CONDITION: 取反
与用户交互:
read [options] VAR...
-p
-t
命令引用:`COMMAND`,$(COMMAND0)
3、总结课程所讲的所有循环语句、条件判断的使用方法及其相关示例
循环语句:
for,while,until
for VAR in LIST;do
循环体
done
LIST生成方法:(1)整数列表
{start..end},$(seq [start [step]] end)
如:for i in {1..10}等于for i in $(seq 1 1 10)
(2)直接给出列表:for i in 1 2 3 4 5 6 7 8 9 10
(3)glob,如:for filename in /var/log/*
(4)命令生成列表,如:for username in $(cut -d: -f1 /etc/passwd)
    算术运算:
          +, -, *, /, %, **
        (1) $[$A+$B]
        (2) $(($A+$B))
        (3) let VARIABLE=$A+$B
        (4) VARIABLE=$(expr $A + $B)
增强型赋值:+=,-=, *=, /=, %=,如:+=相当于
                         sum=$[$sum+$i]
                         let sum+=$i
测试表达式:
          整数测试:-gt, -lt, -ge, -le, -eq, -ne
          字符串测试:==, >, <, !=, -z(字符串长度为0则为真), -n(字符串长度不为0则为真), =~(模式匹配,如:[[ "STRING" =~ PATTERN ]])
          组合测试条件:
                条件间逻辑运算:
                      与:多个条件要同时满足;
                      或:多个条件满足其一即可;
                      非:对指定的条件取反;
               表达式组合:
                      与:[[ CONDITION1 -a CONDITION2 ]]
                      或:[[ CONDITION1 -o CONDITION2 ]]
                      非:[ ! CONDITION ]
               命令组合:
                      与:COMMAND1 && COMMAND2  <-- [ EXPR1 ] && [ EXPR2 ] 
                      或:COMMAND1 || COMMAND2
                      非:! COMMAND
               短路操作符:&&
                    false && true = false
                    false && false = false
                    true && false = true
                    true && true = true
                    if COMMAND1; then
                          COMMAND2
                    fi
              短路操作符:||
                   true || true = true
                   true || false = true
                   false || true = true
                   false || false = false
                     if ! COMMAND1; then
                         COMMAND2
                     fi
                  COMMAND1 && COMMAND2 || COMMAND3,相当于
                      if COMMAND1; then
                                 COMMAND2
                      else
                                COMMAND3
                      fi
多分支if
              if CONDITION1; then
                     if-CONDITION1-true-分支
             elif CONDTION2; then
                   if-CONDITIO2-true-分支
               ...
             else
                   if-ALL-false-分支
             fi
    case语句
        简洁版多分支if语句;    
        使用场景:判断某变量的值是否为多种情形中的一种时使用;
        语法:
             case $VARIABLE in 
             PATTERN1)
                      分支1
                        ;;
            PATTERN2)
                      分支2
                        ;;
            PATTERN3)
                     分支3
                       ;;
            ...
            *)
                    分支n
                       ;;
            esac
          PATTERN可使用glob模式的通配符:
               *: 任意长度的任意字符;
              ?: 任意单个字符;
             []: 指定范围内的任意单个字符;
            a|b: 多选1;
流程控制
while循环:
        while CONDTION; do
                  循环体
        done
            进入条件:当CONDITION为“真”;
            退出条件:当CONDITION为“假”;
        unitl循环:
              until CONDITION; do
                        循环体
                        循环控制变量的修正表达式
              done
                        进入条件:当CONDITION为“假”时
                        退出条件:当CONDITION为“真”时
       循环控制:
              continue [n]:提前结束本轮循环,而直接进入下一轮;
              break [n]:提前结束循环;
     死循环:
         while true; do
                 循环体
                  if CONDTION; then
                          break
                  fi
         done
         until false; do
                  循环体
                  if CONDITION; then
                            break
                  fi
          done
       while循环的特殊用法:
           遍历文件的每一行:while read VARIABLE; do
                                                  循环体
                                          done < /PATH/FROM/SOME_FILE,变量为文件中的每一行
       for循环的特殊用法:
              for ((expr1;expr2;expr3)); do
                       循环体
             done
如:for ((i=1;i<=100;i++))
    函数:
        function: 功能
             把一段具有独立功能代码封装在一起,并给予命名;后续用到时,可直接通过给定函数名来调用整体代码;
             函数作用:
                 代码重用;
                 模块化编程;
                 函数的使用方法:
                         先定义:编写函数代码
                         后调用:给出函数名,还可按需传递参数
                                        定义方法:
                                                   (1) function f_name {
                                                              函数体
                                                         }
                                                    (2) f_name() {
                                                               函数体
                                                          }
                                       调用函数:
                                                      f_name [argu1, argu2, ...]
                                       自定义函数状态返回值:
                                                          return [#]
                                                                   0: 成功
                                                          1-255:失败
注意:函数代码执行时,一旦遇到return,函数代码终止运行,函数返回;
       模块化编程
               功能:把脚本文件中的代码分隔为多段,放在不同的文件中
               假设/root/bin/srv目录有两个文件:
                         (1) 函数文件
                        (2) 脚本文件
      为脚本使用配置文件
               一个文件中只定义变量
               脚本文件source此变量定义的文件
       变量的作用域:
               局部变量:
                   local VARIABLE=value
               存活时间:
                  函数执行开始,至函数返回结束;
4、总结文本处理工具sed及awk的用法;(必须附带示例)
sed:行编辑器,每次读取文件符合模式条件的一行到模式空间,默认不编辑源文件,仅对模式空间的数据做处理,而后将模式空间内容打印至屏幕
     sed [options] ‘AddressCommand‘ file ...
           -n: 静默模式,不再默认显示模式空间中的内容
           -i: 直接修改原文件
           -e SCRIPT -e SCRIPT:可以同时执行多个脚本
           -f /PATH/TO/SED_SCRIPT
     sed -f /path/to/scripts  file
           -r: 表示使用扩展正则表达式
            Address:
                  1、StartLine,EndLine,比如1,100
                        $:最后一行
                  2、/RegExp/,正则表达式来制定模式, 如/^root/
                  3、/pattern1/,/pattern2/,第一次被pattern1匹配到的行开始,至第一次被pattern2匹配到的行结束,这中间的所有行
                  4、LineNumber,指定的行
                  5、StartLine, +N, 从startLine开始,向后的N行;
            Command:
                  d: 删除符合条件的行;删除掉第5行至最后一行的内容
p: 显示符合条件的行;匹配到的行会显示(模式空间和命令处理结果都会显示)2次,如果不需要显示模式空间,需要在前面加-n如:
a \string: 在指定的行后面追加新行,内容为string,如在包含dev的下一行增加aaa
\n:可以用于换行
                  i \string: 在指定的行前面添加新行,内容为string
                  r FILE: 将指定的文件的内容添加至符合条件的行处
w FILE: 将地址指定的范围内的行另存至指定的文件中;注意这会覆盖目标文件
           s/pattern/string/修饰符: 查找并替换,默认只替换每行中第一次被模式匹配到的字符串加修饰符
                                     g: 全局替换
                                     i: 忽略字符大小写
                                        s///: s###, s@@@,如果匹配中包含“/”,可用“#”或者“@”当分隔符 
                                          \(\), \1, \2分组
                                       &: 引用模式匹配整个串
awk:报告生成器,能够将文本中的信息已定义好的格式输出
linux为GNU awk,默认以空格为分割符
使用方法:
#awk [options] ‘script‘ file1 file2...
awk输出:
print:格式,print item1,item2
                 要点:
                        1、各项目之间使用逗号隔开,而输出时则以空白字符分隔,-F可以指定输入分割符,-OFS可以指定输出分割符;如图:
                        2、输出的item可以为字符串或数值、当前记录的字段(如$1)、变量或awk的表达式;数值会先转换为字符串,而后再输出;
                        3、print命令后面的item可以省略,此时其功能相当于print $0, 因此,如果想输出空白行,则需要使用print "";
awk变量:
awk内置变量--记录变量:
FS:输入字段分隔符,默认是空白字符;‘{FS=""}‘
RS:输入行分割符,默认是换行符;
OFS:输出字段分隔符,默认是空白字符;如:
ORS:输出行分割符,默认是换行符;如:
awk内置变量--数据变量:
NR:awk所处理的记录数,如果有多个文件,则会把多个文件处理行统一技计数;
NF:统计当前处理行的字段总数
FNR:当前文件中正在处理的行数,如:

用户自定义变量和赋值变量,如:
awk -v a=“test”
awk ‘{a="test"}‘
printf命令的使用格式:
printf:不会自动打印换行符,与print相比需要指定格式(format)
printf format item1,item2.....
                  format格式的指示符都%开头,后跟一个字符:
                      %c: 显示第一个参数的第一个字母;
                      %d, %i: 十进制整数;
                      %e, %E: 科学计数法显示数值;
                      %f: 显示浮点数;
                      %g, %G: 以科学计数法格式或浮点数格式显示数值;
                      %s: 显示字符串;
                      %u: 显示无符号整数;
                      %%: 显示%自身;
                  修饰符:
                      #:显示宽度
                       -:左对齐,默认为靠右对对齐
                      +:显示数值的符号
                      .#: 取值精度
如:
awk的输出重定向
awk操作符:
算数操作符:+,-,*,/,等
字符串操作符:用于实现字符串连接
赋值操作符:=,+=,-=,--,++等
布尔值:在awk中任何非0或者非空字符串都为真,其余为假
比较操作符:<,<=,>,>=,==,!=,~(模式匹配),!~,subscript in array在某个数组中是否存在某个元素
逻辑操作符:&&,||
条件表达式:
selector?if-true-exp:if-false-exp,相当于以下语句
if selector;then
if-true-exp
else
if-false-exp
fi
如:比较两个数字的大小
awk的模式:awk ‘programe’file1 file2 ..., 其中programe为 pattern { action }
常见的模式类型:
正则表达式:格式为/regular expression/,如:awk -F: ‘/^r/{print $0}‘ /etc/passwd
表达式:其值为非0或者非空是满足条件,如:
awk -F: ‘$3>1013{print $0}‘ /etc/passwd
指定的匹配范围:ranges,格式为pat1,pat2,如:
awk -F: ‘/^r/,/^l/{print $0}‘ /etc/passwd
BEGIN/END: 特殊模式,仅在awk命令的program运行之前(BEGIN)或运行之后(END)执行一次,如:awk -F: END‘{print NF}‘ /etc/passwd,只显示最后一次的结果
如增加表头和表尾:
空模式:匹配任意输入行
常见的Action
表达式
控制语句:
if-else格式:
if (condition) {then body} else {else body}
awk -F: ‘{if ($3>=500) {print $1,"is a common user"} else {print $1, "is an admin or system user"}}‘ /etc/passwd
while格式:
while (condition) {while body}
do-while格式:do {do-while body} while (condition)
for格式:
for (variable assignment; condition; iteration process) {for body}
awk ‘{for (i=1;i<=NF;i+=2){printf "%s ",$i};print ""}‘ /etc/inittab
for循环可用来遍历数组元素:for (i in array) {for body}
case:
switch (expression) {case VALUE or /RGEEXP/: statement1;... default: stementN}
循环控制:continue,break
next:
                              提前结束对本行的处理进而提前进入下一行的处理;
                                   # awk -F: ‘{if($3%2==0) next;print $1,$3}‘ /etc/passwd
                                   # awk -F: ‘{if(NR%2==0) next; print NR,$1}‘ /etc/passwd
数组:
array[index-expression]
index-expression: 可以使用任意字符串; 如果某数组元素事先不存在,那么在引用时,awk会自动创建此元素并将其初始化为空串;因此,要判断某数组是否存在某元素,必须使用“index in array”这种格式
                      要遍历数组中的每一个元素,需要使用如下特殊结构:
                      for (var in array) {for body}, 其var会遍历array的索引;
如统计当前系统连接状态数量:
               常用内置函数:
              split(string,array[,fieldsep[,seps]]):
              功能:将string表示的字符串以fieldsep为分隔符进行切片,并切片后的结果保存至array为名的数组中;数组下标从1开始;
此函数有返回值,返回值为切片后的元素的个数
# netstat -tn | awk ‘/^tcp/{lens=split($5,client,":");ip[client[1]]++}END{for (i in ip) print i,ip[i]}‘
             length(string)
              功能:返回给定字串的长度
             substr(string,start[,length])
             功能:从string中取子串,从start为起始位置为取length长度的子串;
5、写一个脚本:如果某路径不存在,则将其创建为目录;否则显示其存在,并显示内容类型;(不要怀疑,就是这么简单)
        脚本:if [ ! -d $1 ];then
                    echo "$1 is not exist,creat directory $1"
                    mkdir $1
                    echo "done"
                 else
                     echo "directory is exist"
                     ls -l $1
                 fi
6、写一个脚本,完成如下功能;判断给定的两个数值,孰大孰小;给定数值的方法:脚本参数,命令交互;(使用read,依然如此简单)
         脚本参数:if [ $# -gt 0 ];then
                              if [ $1 -gt $2 ];then
                                 echo "$1 is greater than $2"
                             elif [ $1 -lt $2 ];then
                                 echo "$2 is greater than $1"
                             else
                                 echo "two parameters have the same value"
                              fi
                        else
                              echo "please input two parameters"
                              exit 8
                         fi
        命令交互:tip="Please input two number:"
                         read -p  "$tip" a b
                        (( $a )) && (( $b )) 2> /dev/null
                         if [ $? = 0 ];then
                            if [ $a -gt $b ];then
                               echo "a is greater than b"
                           elif [ $a -lt $b ];then
                                echo "b is greater than a"
                            else
                                echo "two parameters have the same value"
                            fi
                      else
                           echo "please input two interger number"
                      fi
7、求100以内所有奇数之和(至少用3种方法)
     for循环:
       sum=0
       for i in $(seq 1 2 100);do
              sum=$[$sum+$i]
       done
       echo $sum
     while循环:
          sum=0
          j=1
          while [ $j -lt 100 ];do
                sum=$(($sum+$j))
                    j=$(($j+2))
           done
           echo $sum
until循环:
sum=0
          k=1
          until [ $k -gt 100 ];do
                  sum=$(($sum+$k))
                  k=$(($k+2))
         done
         echo $sum
8、写一个脚本实现如下功能:
(1) 传递两个文本文件路径给脚本;
(2) 显示两个文件中空白行数较多的文件及其空白行的个数;
(3) 显示两个文件中总行数较多的文件及其总行数;
9、写一个脚本
(1) 提示用户输入一个字符串;
(2) 判断:
如果输入的是quit,则退出脚本;
否则,则显示其输入的字符串内容;
10、写一个脚本,打印2^n表;n等于一个用户输入的值;
11、写一个脚本,写这么几个函数:函数1、实现给定的两个数值的之和;函数2、取给定两个数值的最大公约数;函数3、取给定两个数值的最小公倍数;关于函数的选定、两个数值的大小都将通过交互式输入来提供。
本文出自 “^狐狸尾巴$” 博客,请务必保留此出处http://nikanke.blog.51cto.com/986378/1700644
linux运维实战练习-2015年9月13日-9月15日课程作业
原文地址:http://nikanke.blog.51cto.com/986378/1700644