LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
查看: 1743|回复: 19

一个学unix shell 都要考试的电话本程序

[复制链接]
发表于 2005-3-11 14:12:06 | 显示全部楼层 |阅读模式
概述:实现基本的查询,新增,删除,修改以及借用,合并多人的电话本数据文件之功能!
包含:几乎所有unix shell最基本的命令(awk,sed,grep,sort..)和基本语法(函数,变量,环境..)
要点:注意程序的交互友好性和可读可维护性,以及代码的简洁合理性。
             以下做为参考,限于本人水平,欢迎大家加以完善和优化
。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。

  1. #!/bin/bash   
  2. #(注意 上句  内容不可以有其他,后面不能加其他,保护用#注释内容,特别)
  3. #(以下命令用bash shell 来解释 :提示:shell有多种类型,如ksh,csh,rsh...)
  4. #declare whole variable phonebook
  5. phonebook=~/phonebook    #(次程序用到的电话本数据文件)
  6. trap "" 2                              #(忽略中断干扰)
  7. # initialize field definition
  8. # save field to use saparator ^ in a entry    #(phonebook中字段用^分隔来存储有#如/etc/passwd)
  9. phbook[0]="name"             #not be omitted
  10. phbook[1]="mail"             #not be omitted
  11. phbook[2]="telnum"
  12. phbook[3]="birthday"                           
  13. phbook[4]="sex"
  14. phbook[5]="remark"     #not more than 30 words
  15. if [ ! -e "$phonebook" ]                  #(给用户初始化一个phonebook,如果HOME下不能写,就退出)
  16. then
  17.    echo "$phonebook not exist!"
  18.    echo -e "Should I create it for you,(yes/no) \c"
  19.    read -r answer
  20.    if [ "$answer" != yes -o "$answer" != y ]
  21.    then
  22.       echo "Not Create !"
  23.       echo "You can choise "8" to try to use other phonebook"
  24.       exit 1
  25.    fi
  26.    > ~/phonebook 2>/dev/null
  27.    if [ $? != 0 ]
  28.    then
  29.       echo "Create failure!"
  30.       echo "Failure possibly is due to directory attribute"
  31.       exit 1
  32.    fi
  33. elif [ ! -f $phonebook ]
  34. then
  35.    echo "$phonebook is not a common file"
  36.    exit 1   
  37. fi
  38. # format output entry, used by other function       #(先定义函数,为了后面的应用)
  39. display () { entry="$1^"                            #(显示函数,格式化输出技巧)
  40.              OIFS=$IFS                              #(注意数组的使用,循环结构)
  41.              IFS=^
  42.              set -- $entry
  43.              IFS=$OIFS
  44.              echo
  45.              echo "============================================"
  46.              typeset -i j=0
  47.              for i
  48.              do
  49.                printf "| %-9.9s:%-30.30s |\n" "${phbook[j]}" "$i"
  50.                j=$((j+1))
  51.              done
  52.              echo "============================================"
  53.              echo "Press Enter to continue..."
  54.             }
  55. #lu: locate entry ,it is about to used as a funtion
  56. lu () { grep -i "^$1\^"  $phonebook >/tmp/lumatch$$
  57.         if [ $? != 0 ]
  58.         then
  59.           echo "$1 not found "
  60.         else
  61.           lumatch="$(cat /tmp/lumatch$$)"
  62.           display "$lumatch"
  63.           rm -f /tmp/lumatch$$
  64.         fi
  65.       }
  66. #add: add a entry register in being used phonebook
  67. add () { echo "$1" >>$phonebook
  68.          sort -uo $phonebook $phonebook
  69.          info=$(echo "$1" |awk -F'^' '{print $1}')
  70.          echo "$info succeeded to add"
  71.        }
  72. #change: change a entry
  73. change () { grep -i "^$1\^" $phonebook >/tmp/chmatch$$
  74.             if [ ! -s /tmp/chmatch$$ ]
  75.             then
  76.                echo "$1 not found"
  77.                rm -f /tmp/chmatch$$
  78.             else
  79.                chmatch="$(cat /tmp/chmatch$$)"
  80.                display "$chmatch"
  81.                echo -e "change this entry register (yes/no): \c"
  82.                read -r answer
  83.                if [ "$answer" != y -a "$answer" != yes ]
  84.                then
  85.                   echo -e "not to change entry"
  86.                   rm -f /tmp/chmatch$$                 
  87.                else                                      #(下面命令很重要,学会有助与shell)
  88.                   cut -d"^" -f2- /tmp/chmatch$$ >/tmp/chmatch2$$
  89.                   tr '^' '\n' < /tmp/chmatch2$$ >/tmp/chmatch$$
  90.                   vi /tmp/chmatch$$
  91.                   echo "$1" >/tmp/chmatch3$$
  92.                   cat /tmp/chmatch3$$ /tmp/chmatch$$ >/tmp/chmatch2$$
  93.                   sed -n '1,6p' /tmp/chmatch2$$ >/tmp/chmatch$$
  94.                   paste -d"^" -s /tmp/chmatch$$ >/tmp/chmatch2$$
  95.                   grep -v "^$1\^" $phonebook >/tmp/phonebook2$$
  96.                   cat /tmp/chmatch2$$ >>/tmp/phonebook2$$
  97.                   sort -o /tmp/phonebook2$$ /tmp/phonebook2$$
  98.                   cp /tmp/phonebook2$$ $phonebook
  99.                   rm -f /tmp/chmatch$$ /tmp/chmatch[2-3]$$ /tmp/phonebook2$$
  100.                   echo -e "Succeed in changing "$1" entry register"
  101.               fi
  102.            fi
  103.           }
  104. #rem: delete a entry ,it is a funtion
  105. rem () { grep -i "^$1\^" $phonebook >/tmp/remmatch$$
  106.          if [ $? != 0 ]
  107.          then
  108.             echo "$1 not found "
  109.             rm -f /tmp/rematch$$
  110.          else
  111.             remmatch="$(cat /tmp/remmatch$$)"
  112.             display "$remmatch"
  113.             rm -f /tmp/remmatch$$
  114.             echo
  115.             echo -e "delete this entry, (yes/no) \c"
  116.             read -r answer
  117.             if [ "$answer" = y -o "$answer" = yes ]
  118.             then
  119.                sed "/^$1\^/d" $phonebook >/tmp/phonebook$$
  120.                cp /tmp/phonebook$$ $phonebook
  121.                rm -f /tmp/phonebook$$
  122.                echo "$1 succeeded to be deleted"
  123.             else
  124.                echo -e "$1 not deleted!"
  125.             fi
  126.           fi
  127.        }
  128. #showlist: to show all the content of being used phonebook
  129. showlist () {  echo
  130.                echo "================================================"
  131.                printf "| %-30.30s  %-30.30s\n" "${phbook[0] |}" "${phbook[1]}"
  132.                awk -F'^' '{printf "| %-30.30s %-30.30s |\n" ,$1,$2}' $phonebook \
  133.                |more
  134.                echo "================================================"
  135.               }
  136. #to combine another phonebook and join up
  137. joindb () {   grep "^" "$1" >/tmp/joindb$$
  138.               if [ $? != 0 ]
  139.               then
  140.                 echo "not matched database"
  141.                 rm -f /tmp/joindb$$
  142.                 exit 1
  143.               fi
  144.               cat /tmp/joindb$$ >> $phonebook
  145.               sort -uo $phonebook $phonebook
  146.               rm -f /tmp/joindb$$
  147.               echo "succeed in incorporating database "
  148.            }         
  149. #(程序初始化完成,下面就是次shell主体,注意循环的使用,和友好性)
  150. #(考虑到反复操作大量数据的可能,所以再操作后不退出,致使代码有重复现象)
  151. # initialization finished ,main shell now start implementing
  152. until [ "$choice" = 0 ]
  153. do
  154. echo -e "
  155.    this is a process about telphone book operation
  156.    would you like to:
  157.       
  158.     1. Look someone up
  159.     2. Add someone to the phone book
  160.     3. Delete someone register from the phonebook
  161.     4. Change a entry register
  162.     7. Show all the  phonebook content
  163.     8. borrow other phonebook
  164.     9. join another phonebook to current with  ^ fields separator
  165.     0. exit program
  166.   please select one of the above (1-4): \c "
  167. read -r choice
  168. echo
  169. case "$choice"
  170. in
  171.    1) echo -e "Enter name to look up: \c"
  172.       read -r name
  173.       name="$(echo "$name" |tr -d "^")"
  174.       lu "$name"
  175.       echo
  176.       while true
  177.       do
  178.          echo -e "continue lookup,(yes/no): \c "
  179.          read -r answer
  180.          if [ "$answer" = n -o "$answer" = no ]
  181.          then
  182.              continue 2
  183.          else
  184.               echo -e "Enter name to look up: \c"
  185.               read -r  name              #(学会过滤不必要的输入内容,注意read -r的使用)
  186.               name="$(echo "$name" |tr -d "^")"
  187.               lu "$name"
  188.          fi
  189.        done ;;
  190. #2 for indenting script ,temporarily name function
  191.    2) addtemp () {
  192.       echo -e "Enter name: \c"
  193.       read -r name
  194.       while  [ "$name" = "" ]
  195.        do
  196.           echo -e "Enter name: \c"
  197.           read -r name
  198.        done
  199.       name="$(echo "$name" |tr -d "^")"
  200.       grep -i "^$name\^" $phonebook >/dev/null
  201.       while [ $? = 0 ]
  202.       do
  203.          echo
  204.          echo -e "$name had existed,key in other name"
  205.          continue 2
  206.       done
  207.       echo -e "Enter mailbox: \c"
  208.       read -r mailbox
  209.       echo "$mailbox" |grep "@" >/dev/null
  210.       mailflag=$?
  211.       while  [ "$mailbox" = "" -o "$mailflag" != 0 ]
  212.        do
  213.          echo -e "Enter mailbox and include '@' char : \c"
  214.          read -r mailbox
  215.          echo "$mailbox" |grep "@" >/dev/null
  216.          mailflag=$?
  217.        done
  218.       mailbox="$(echo "$mailbox" |tr -d "^")"
  219.       echo -e "Enter phone number: \c"
  220.       read -r telnum
  221.       telnum="$(echo "$telnum" |tr -d "^")"
  222.       echo -e "Enter birthday: \c"
  223.       read -r birthday
  224.       birthday="$(echo "$birthday" |tr -d "^")"
  225.       echo -e "Enter sex: \c"
  226.       read -r sex
  227.       sex="$(echo "$sex" |tr -d "^")"
  228.       echo -e "Enter remark: \c"
  229.       read -r remark
  230.       remark="$(echo "$remark" |tr -d "^")"
  231.      }
  232.       addtemp
  233.       add "$name^$mailbox^$telnum^$birthday^$sex^$remark"
  234.       echo
  235.       while true
  236.        do
  237.           echo -e "continue add,(yes/no): \c "
  238.           read -r answer
  239.           if [ "$answer" = n -o "$answer" = no ]
  240.             then
  241.                continue 2
  242.            else
  243.                addtemp
  244.                add "$name^$mailbox^$telnum^$birthday^$sex^$remark"
  245.                echo
  246.            fi
  247.       done ;;
  248. #3 for indenting script, temporarily name funtion
  249.    3) deltemp () { echo -e "Enter name to be deleted: \c"
  250.       read -r name
  251.       while  [ "$name" = "" ]
  252.        do
  253.           echo -e "Enter name to be deleted: \c"
  254.           read -r name
  255.        done
  256.       name="$(echo "$name" |tr -d "^")"
  257.                 }
  258.       deltemp
  259.       rem "$name"
  260.       echo
  261.       while true
  262.        do
  263.           echo -e "continue rem,(yes/no): \c "
  264.           read -r answer
  265.           if [ "$answer" = n -o "$answer" = no ]
  266.             then
  267.                continue 2
  268.            else
  269.               deltemp
  270.               rem "$name"
  271.               echo
  272.            fi
  273.        done ;;
  274.    4 ) changetemp () { echo -e "Enter name to be changed: \c"
  275.        read -r name
  276.        while  [ "$name" = "" ]
  277.        do
  278.           echo -e "Enter name to be changed: \c"
  279.           read -r name
  280.        done
  281.        name="$(echo "$name" |tr -d "^")"
  282.                       }
  283.        changetemp
  284.        change "$name"
  285.        echo
  286.        while true
  287.        do
  288.           echo -e "continue change,(yes/no): \c "
  289.           read -r answer
  290.           if [ "$answer" = n -o "$answer" = no ]
  291.           then
  292.                continue 2
  293.           else
  294.               changetemp
  295.               change "$name"
  296.               echo
  297.            fi
  298.        done ;;
  299.    7 ) echo " **********************phonebook content***********************"
  300.       showlist
  301.       echo " **************************************************************"
  302.       ;;
  303.    8)    echo -e "Enter a username with holding phonebook: \c"
  304.          read -r name
  305.    eval  phonebook2=~$name/phonebook
  306.          while [ ! -f "$phonebook2" ]
  307.          do
  308.             echo -e "$phonebook2 not exist;continue try (yes/no): \c"
  309.             read -r answer
  310.             if [ "$answer" != y -a "$answer" != yes ]
  311.             then
  312.                continue 2
  313.             fi
  314.             echo -e "Enter a username with holding phonebook: \c"
  315.             read -r name
  316.     eval    phonebook2=~$name/phonebook
  317.          done
  318.          if [ $phonebook = $phonebook2 ]
  319.          then
  320.             echo
  321.             echo "operation succeed ,then user is yourself"
  322.          else
  323.             echo
  324.             echo "succeed in  borrowing $name's phonebook"
  325.          fi
  326.          phonebook=$phonebook2
  327.          echo
  328.        ;;
  329. #9 for indenting script ,temporarily name fucntion
  330.    9) jointemp ()  { echo -e "Enter a username with holding phonebook: \c"
  331.       read -r name
  332. eval  phonebook2=~$name/phonebook
  333.       until  [ -f "$phonebook2" -a -s "$phonebook2" -a "$phonebook2" \
  334.               != "$phonebook" ]
  335.       do
  336.           echo -e "$phonebook2 not exits or current;continue try (yes/no): \c"
  337.           read -r answer
  338.           if [ "$answer" != y -a "$answer" != yes ]
  339.           then
  340.               continue 2
  341.           fi
  342.           echo -e "Enter a username with holding phonebook: \c"
  343.           read -r name
  344. eval      phonebook2=~$name/phonebook
  345.       done
  346.                    }
  347.       jointemp
  348.       joindb "$phonebook2"
  349.       echo
  350.       while true
  351.       do
  352.           echo -e "continue join database (yes/no):  \c "
  353.           read -r answer
  354.           if [ "$answer" != yes -a "$answer" = y ]
  355.           then
  356.                continue 2
  357.           else
  358.                jointemp
  359.                joindb "$phonebook2"
  360.                echo
  361.           fi
  362.       done
  363.       ;;
  364.    0) exit 1 ;;
  365.    *) echo  "Bad choice" ;;  
  366. esac
  367. done
复制代码
发表于 2005-3-12 19:03:23 | 显示全部楼层
呵呵,兄弟这个一定是作业来的吧?
不知道效果如何,兄弟下次帖代码时用[PHP][/PHP]标签合起来就不会有上面的表情出现了:),因为有些地方不知道代码是什么,兄弟方便可在楼下再帖一次
回复 支持 反对

使用道具 举报

 楼主| 发表于 2005-3-15 16:36:36 | 显示全部楼层
呵呵。可以。 不过和你们的作业要求不尽相同,字段定义不同: 功能比你们要求的多
也是我学完shell的作品而已。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2005-3-15 17:20:44 | 显示全部楼层
笑脸处代码为:  
  printf "| %-9.9s:%-30.30s |\n" "${phbook[j]}" "$i"  
笑脸为  :   和   %   如(AB)  ,不能写倒一起去,一些就变了笑脸。哈哈
回复 支持 反对

使用道具 举报

发表于 2005-3-16 11:27:03 | 显示全部楼层

运行提示“bad interpreter”

运行提示“bad interpreter”
回复 支持 反对

使用道具 举报

发表于 2005-3-16 13:03:22 | 显示全部楼层
呵呵,楼上的兄弟不要把整段复制下来不作改动啊,楼主注释的不是很好
用了()号,呵呵,就在后面用#的话就可以复制下来不改动
回复 支持 反对

使用道具 举报

发表于 2005-3-16 16:45:18 | 显示全部楼层

我已经把()都去掉了,还是有错误

我已经把()都去掉了,还是有错误
回复 支持 反对

使用道具 举报

 楼主| 发表于 2005-3-18 22:55:56 | 显示全部楼层
已经修改过了, 的确是不能运行以前的,不是代码错误,而是如下:
1: 注释位置  :第一行 #!/bin/bash 后面不可以有其他内容, 我注释没注意,歉意!
2: 注释符号 # 写成了 中文输入法的# ,不一样。
现在可以了。你可以把它复制到你 linux下
注意只要你 HOME目录下,(一般是 /home/你登陆名 )新建vi 一个文件,然后 注意+可执行权限
chmod +x  文件  , 然后就OK了
回复 支持 反对

使用道具 举报

发表于 2005-3-21 11:05:02 | 显示全部楼层

再次运行提示“:没有那个文件或目录”

再次运行提示“:没有那个文件或目录”
不好意思我是新手,能不能把你的源文件放上来。谢谢
回复 支持 反对

使用道具 举报

发表于 2005-3-21 18:55:02 | 显示全部楼层
借用是什么意思~~? 说不定我可以帮你哦~!! 呵呵~
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表