LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
楼主: KornLee

【shell脚本欣赏区】:[展示你的作品的好去处!欢迎投帖]

[复制链接]
 楼主| 发表于 2003-4-28 18:10:51 | 显示全部楼层

自动挂载WINDOWS下的分区的脚本

特别感谢作者:ywchen2000兄

Linux开机自动挂载WINDOWS下的分区
笔者有两快硬盘,其中第一块硬盘装了WindowsMe,第二快装了Win2000和red hat
linux7.2,在WINDOWS环境中,笔者划分了四个分区,每次在LINUX环境中要想看这四个区的内
容都要输入一大堆的命令,非常麻烦.近来学习了SHELL编程,想到了一个解决方法.现在写出
来与大家分享.
首先,打开一个虚拟终端,输入vi mymount,然后按insert键,输入以下代码:
#!/bin/bash
case $1 in
m)
mount -o iocharset=cp936 -t vfat /dev/hda5 /mnt/winme
mount -o iocharset=cp936 -t vfat /dev/hda6 /mnt/temp
mount -o iocharset=cp936 -t vfat /dev/hdc1 /mnt/win2000
mount -o iocharset=cp936 -t vfat /dev/hdc2 /mnt/share
;;
u)
umount -o iocharset=cp936 -t vfat /dev/hda5 /mnt/winme
umount -o iocharset=cp936 -t vfat /dev/hda6 /mnt/temp
umount -o iocharset=cp936 -t vfat /dev/hdc1 /mnt/win2000
umount -o iocharset=cp936 -t vfat /dev/hdc2 /mnt/share
;;
esac
按Esc输入:wq回车就可以了.
现在让我来解释一下这些代码.第一行#!/bin/bash指定以bash shell执行此文
件.case $1 in 为取的命令行参数.若为m则开始挂载,若为u则卸载.其中-o
iocharset=cp936能够显示中文名.-t vfat 为指定文件系统类型为WINDOWS下的VFAT文件系
统.winme temp win2000和share为目录/mnt下的子目录.

好了,该程序已经写好了.但是它还没有执行权利.我们只要输入下面这个命令就可以了.
chmod u+x mymount
呵呵,到这步你只要输入./mymount m,就可以挂载了.不过笔者比较懒,觉得这样做比较麻
烦.于是就请教了一些高手,终于解决了这个问题呀.呵呵.在/etc/rc.d/rc.local 文件中输
入 sh ./root/mymount m就可以了.
重新启动你的电脑,进入LINUX看看是否自动挂载.呵呵.笔者以后就非常轻松,不需要输入
那么多的命令了.爽呀.
发表于 2003-4-30 09:40:14 | 显示全部楼层
作者 plan9 [原创]
输出目录树:

一个输效果基本和tree命令的输出完全一样(除了目录未的工作不同),文件带色彩输出,文件、目录数统计,贴上来给大家做个参考:

tree.sh
------------------------------------------------------------

  1. #!/bin/sh
  2. #
  3. # tree.sh
  4. # A tool that display the dictionary structure in dos's
  5. # tree command style.
  6. # By Matthew <matthew@linuxforum.net>
  7. #
  8. #    __@
  9. #  _ \<_
  10. # (_)/(_)
  11. # Apr 29 2003
  12. #
  13. # Tested on slackware, openbsd, netbsd, freebsd.
  14. #
  15. # Just for fun.
  16. #

  17. # The name of the ls program, please use
  18. # the absolute path, otherwise, there
  19. # may be get some strange errors.
  20. #
  21. LSPROG="/bin/ls"

  22. # COLOR DEFINE
  23. # ============
  24. #
  25. DIR="\033[01;34m"
  26. EXE="\033[01;32m"
  27. DEV="\033[01;33m"
  28. LNK="\033[01;36m"
  29. ZIP="\033[01;31m"
  30. SOCK="\033[01;35m"
  31. NULL="\033[00m"

  32. ROOT=${1:-.}
  33. TRUE=0
  34. FALSE=1
  35. LAYERS=0
  36. FILECOUNT=0
  37. DIRCOUNT=0

  38. # print_dash
  39. # ==========
  40. # Print the structure lines
  41. #
  42. print_dash()
  43. {
  44.         local i=0
  45.         local num=$1
  46.        
  47.         while [ $i -lt $num ]; do
  48.                 echo -n "|"
  49.                 for j in 1 2 3; do
  50.                         echo -n " "
  51.                 done

  52.                 i=`expr $i + 1`
  53.         done

  54.         echo -n "|-- "
  55. }

  56. # ispkg
  57. # =====
  58. # Test if the file is a package like:
  59. # .gz .tar .tgz .tar.gz .zip .rar .rpm
  60. # and etc.
  61. #
  62. ispkg()
  63. {
  64.         local f=$1
  65.         local i       

  66.         # Package extension list, you can add your coustom
  67.         # extensions in it.
  68.         #
  69.         local pkg__ext=".gz .tar .tgz .tar.gz .zip .rar .rpm"

  70.         # if the file's suffix contain any package extension
  71.         # then cut it.

  72.         for i in $pkg__ext; do
  73.                 f=${f%$i}
  74.         done

  75.         if [ "$f" != "$1" ]; then
  76.                 return $TRUE
  77.         else
  78.                 return $FALSE
  79.         fi
  80. }

  81. # mktree
  82. # ======
  83. # The main function, that print the
  84. # dictionary structure in dos's tree
  85. # command style. It's runs in nesting.
  86. #
  87. mktree()
  88. {
  89.         local f
  90.         for f in `$LSPROG -1 $1 2> /dev/null`; do
  91.                 f=${f%/}
  92.                 f=${f##*/}
  93.        
  94.                 # If dictionary then print it and enter
  95.                 # the nesting block.
  96.                 if [ -d $1/$f ]; then
  97.                         print_dash $LAYERS
  98.                         echo -e "${DIR}$f${NULL}"
  99.                         DIRCOUNT=`expr $DIRCOUNT + 1`

  100.                         LAYERS=`expr $LAYERS + 1`
  101.                         mktree $1/$f
  102.                 else
  103.                         print_dash $LAYERS
  104.                         # file is a symbol link
  105.                         if [ -L $1/$f ]; then
  106.                                 echo -e "${LNK}$f${NULL}"
  107.                         # file is executable
  108.                         elif [ -x $1/$f ]; then
  109.                                 echo -e "${EXE}$f${NULL}"
  110.                         # file is a device
  111.                         elif [ -c $1/$f -o -b $1/$f ]; then
  112.                                 echo -e "${DEV}$f${NULL}"
  113.                         # file is a socket
  114.                         elif [ -S $1/$f ]; then
  115.                                 echo -e "${SOCK}$f${NULL}"
  116.                         # file is a package
  117.                         elif `ispkg $f`; then
  118.                                 echo -e "${ZIP}$f${NULL}"
  119.                         else       
  120.                                 echo -e "$f"
  121.                         fi
  122.                        
  123.                         FILECOUNT=`expr $FILECOUNT + 1`
  124.                 fi
  125.         done

  126.         LAYERS=`expr $LAYERS - 1`
  127. }

  128. echo $ROOT
  129. mktree $ROOT
  130. echo "\`"
  131. echo "$DIRCOUNT directories, $FILECOUNT files"
复制代码


显示效果:

  1. /home/matthew/
  2. |-- [color=#0000ff]src[/color]
  3. |   |-- [color=#0000ff]asm[/color]
  4. |   |   |-- hello.s
  5. |   |   |-- shell.s
  6. |   |   |-- [color=#00ff00]hello[/color]
  7. |   |   |-- [color=#00ff00]shell[/color]
  8. |   |-- [color=#0000ff]shell[/color]
  9. |   |   |-- [color=#00ff00]tree.sh[/color]
  10. |-- [color=#ff0000]xfce.tar.gz[/color]
  11. |-- mbox
  12. `
  13. 3 directories, 7 files
复制代码
 楼主| 发表于 2003-5-6 02:02:14 | 显示全部楼层

BASH调试器

感谢作者YOO兄[原创]
  1. bashdb.sh负责生成debug档
  2. #!/bin/bash
  3. #bashdb - bash debugger
  4. #该脚本将bashbd.pre和目标脚本处理成调试脚本
  5. echo 'bash Debugger version 1.0'
  6. _dbname=${0##*/}
  7. if (( $# < 1 )); then
  8.     echo "$_dbname: Usage: $_dbname filename" >&2
  9.     exit 1
  10. fi
  11. _guineapig=$1
  12. if [ ! -r $1 ]; then
  13.     echo "$_dbname: Cannot read file '$_guineapig'." >&2
  14.     exit 1
  15. fi
  16. shift
  17. _tmpdir=/tmp
  18. _libdir=.
  19. _debugfile=$_tmpdir/bashdb.$$       #正在被调试脚本的临时文件
  20. cat $_libdir/bashdb.pre $_guineapig > $_debugfile
  21. exec bash $_debugfile $_guineapig $_tmpdir $_libdir "$@"
  22. bashdb.pre负责对被调试函数进行预处理
  23. 源码:
  24. #!/bin/bash
  25. #bashdb预处理部分
  26. #本文件预处理被调试的shell脚本
  27. #参数:
  28. #$1=初始试验脚本的名字
  29. #$2=临时文件所保存在的目录
  30. #$3=bashdb.pre和bashdb.fns被保存的目录
  31. _debugfile=$0
  32. _guineapig=$1
  33. _tmpdir=$2
  34. _libdir=$3
  35. shift 3
  36. source $_libdir/bashdb.fns
  37. declare -a _linebp
  38. let _trace=0
  39. let _i=1
  40. while read; do
  41.     _lines[$_i]=$REPLY
  42.     let _i=$_i+1
  43. done < $_guineapig
  44. trap _cleanup EXIT
  45. let _steps=1
  46. LINENO=-2
  47. trap '_steptrap $LINENO' DEBUG
  48. bashdb.fns包含了DEBUG调用的调试函数
  49. 源码:
  50. #!/bin/bash
  51. #测试脚本的每行被执行之后,shell进入本函数
  52. function _steptrap
  53. {
  54.         _curline=$1             #当前运行行的行号
  55.         (( $_trace )) && _msg "$PS4 line $_curline: ${_lines[$_curline]}"
  56.         if (( $_steps >= 0 )); then
  57.                 let _steps=$_steps-1
  58.         fi
  59.         #首先查看是否达到行编号断点
  60.         #如果达到,则进入调试器
  61.         if _at_linenumbp ; then
  62.                 _msg "Reached breakpoint at line $_curline"
  63.                 _cmdloop
  64.         
  65.         #如果没有达到,则检查是否有中断条件存在且为真
  66.         #如果是,则进入调试器
  67.         elif [ -n "$_brcond" ] && eval $_brcond; then
  68.                 _msg "Bread condition $_brcond true at line $_curline"
  69.                 _cmdloop
  70.         
  71.         #如果不是,则检查是否在采用步进方式,步数是否达到。如果是,则进入调试器
  72.         elif (( $_steps == 0 )); then
  73.                 _msg "Stopped at line $_curline"
  74.                 _cmdloop
  75.         fi
  76. }
  77. #调试器命令循环
  78. function _cmdloop {
  79.         local cmd args
  80.         while read -e -p "bashdb> " cmd args; do
  81.                 case $cmd in
  82.                         h ) _menu ;;                                    #打印命令菜单
  83.                         bc) _setbc $args ;;                             #设置中断条件
  84.                         bp) _setbp $args ;;                             #设置断点在给定行
  85.                         cb) _clearbp $args ;;                   #清除一个或所有断点
  86.                         ds) _displayscript ;;                   #列出脚本并显示断点
  87.                         g ) return ;;                                   #开始/再继续执行脚本
  88.                         q ) exit ;;                                             #退出
  89.                         s ) let _steps=${args:-1}               #单步执行N次(默认为1)
  90.                                 return ;;
  91.                         x ) _xtrace ;;                                  #切换执行追踪
  92.                         !*) eval ${cmd#!} $args ;;              #传递给shell
  93.                         * ) _msg "Invalid command: '$cmd'" ;;
  94.                 esac
  95.         done
  96. }
  97. #查看这个行编号是否有一个断点
  98. function _at_linenumbp
  99. {
  100.         local i=0
  101.         #循环遍历断点数组并查看它们是否与当前行编号匹配。如果匹配就返回真(0),
  102.         #否则就返回假
  103.         if [ "$_linebp" ]; then
  104.                 while (( $i < ${#_linebp[@]} )); do
  105.                         if (( ${_linebp[$i]} == $_curline )); then
  106.                                 return 0
  107.                         fi
  108.                         let i=$i+1
  109.                 done
  110.         fi
  111.         return 1
  112. }
  113. #设置断点在给定的行编号或列出断点
  114. function _setbp
  115. {
  116.         local i
  117.         #如果无参数,调用断点列表函数。否则查看参数是否为正数
  118.         #如果不是,则打印错误消息。如果是,则查看行编号是否包含文本
  119.         #如果不是则打印错误信息。如果是,则回应当前断点和新的附加。并将它们
  120.         #输送到"排序",并将结果赋值给断点列表。这将导致断点按数字顺序排列
  121.         #注意,使用-u选项可以删除重复的断点
  122.         if [ -z "$1" ]; then
  123.                 _listbp
  124.         elif [ $(echo $1 | grep '^[0-9]*') ]; then
  125.                 if [ -n "${_lines[$1]}" ]; then
  126.                         _linebp=($(echo $( (for i in "${_linebp[*]} $1"; do
  127.                                         echo $i; done) | sort -n) ))
  128.                         _msg "Breakpoint set at line $1"
  129.                 else
  130.                         _msg "Breakpoints can only be set on non-blank lines"
  131.                 fi
  132.         else
  133.                 _msg "Please specify a numeric line number"
  134.         fi
  135. }
  136. #列出断点及中断条件
  137. function _listbp
  138. {
  139.         if [ -n "$_linebp" ]; then
  140.                 _msg "Breakpoints at lines: ${_linebp[*]}"
  141.         else
  142.                 _msg "No breakpoints have been set"
  143.         fi
  144.         _msg "Break on condition:"
  145.         _msg "$_brcond"
  146. }
  147. #清除单个或所有断点
  148. function _clearbp
  149. {
  150.         local i bps
  151.         #如果没有参数,那么删除所有断点。否则查看参数是否为正数,如果不是
  152.         #则打印错误消息。如果是,则回应除被传递的那个之外的所有当前断点
  153.         #并将它们赋值给局部变量。(我们需要这样做是因为将它们赋值给_linebp
  154.         #将使数组保持在同一大小并将值向回移动一位置,导致重复值)。然后销毁旧数组
  155.         #并将局部数组中的元素赋值,于是我们高效地重创了它,减掉了被传递的断点
  156.         if [ -z "$1" ]; then
  157.                 unset _linebp[*]
  158.                 _msg "All breakpoints have been cleared"
  159.         elif [ $(echo $1 | grep '^[0-9]*') ]; then
  160.                 bps=($(echo $(for i in ${_linebp[*]}; do
  161.                                 if (( $1 != $i )); then echo $i; fi; done) ))
  162.                 unset _linebp[*]
  163.                 _linebp=(${bps[*]})
  164.                 _msg "Breakpoint cleared at line $1"
  165.         else
  166.                 _msg "Please specify a numeric line number"
  167.         fi
  168. }
  169. #设置或清除中断条件
  170. function _setbc
  171. {
  172.         if [ -n "$*" ]; then
  173.                 _brcond=$args
  174.                 _msg "Break when true: $_brcond"
  175.         else
  176.                 _brcond=
  177.                 _msg "Break condition cleared"
  178.         fi
  179. }
  180. #打印出shell脚本并标出断点的位置以及当前行
  181. function _displayscript
  182. {
  183.         local i=1 j=0 bp cl
  184.         ( while (( $i <= ${#_lines[@]} )); do
  185.                 if [ ${_linebp[$j]} ] && (( ${_linebp[$j]} == $i )); then
  186.                         bp='*'
  187.                         let j=$j+1
  188.                 else
  189.                         bp=' '
  190.                 fi
  191.                 if (( $_curline == $i )); then
  192.                         cl=">"
  193.                 else
  194.                         cl=" "
  195.                 fi
  196.                 echo "$i:$bp $cl ${_lines[$i]}"
  197.                 let i=$i+1
  198.          done
  199.         ) | more
  200. }
  201. #切换执行追踪on/off
  202. function _xtrace
  203. {
  204.         let _trace="! $_trace"
  205.         _msg "Execution trace "
  206.         if (( $_trace )); then
  207.                 _msg "on"
  208.         else
  209.                 _msg "off"
  210.         fi
  211. }
  212. #打印传进来的参数到标准错误
  213. function _msg
  214. {
  215.         echo -e "$@" >&2
  216. }
  217. #打印命令菜单
  218. function _menu {
  219.         _msg 'bashdb commands:
  220.         bp N            set breakpoint at line N
  221.         bp              list breakpoints and break condition
  222.         bc string       set break condition to string
  223.         bc              clear break condition
  224.         cb N            clear breakpoint at line N
  225.         cb              clear all breakpoints
  226.         ds              displays the test script and breakpoints
  227.         g               start/resume execution
  228.         s [N]           execute N statements (default 1)
  229.         x               toggle execution trace on/off
  230.         h,?             print this menu
  231.         ! string        passes string to a shell
  232.         q               quit'
  233. }
  234. #退出之前删除临时文件
  235. function _cleanup
  236. {
  237.         rm $_debugfile 2>/dev/null
  238. }  
复制代码
 楼主| 发表于 2003-5-8 23:22:54 | 显示全部楼层

一个查看分区信息的脚本


来自:http://www.redhat.com

The msinfo.sh script

This shell script analyses the boot sector of the given partition and displays some information along with the "Total Special Sectors" in a message box. It
assumes that the filesystem on the given partition is a FAT16. If not, it will print an error message and exit. Invoke it as

# msinfo <partition name>

To run this script, you will need the "dialog" program that displays dialog boxes. You can get it from here.
  1. #!/bin/sh
  2. #
  3. # msinfo.sh           This shell script displays the boot sector of the
  4. #                     given partition.
  5. #
  6. # Author:             Rahul U. Joshi
  7. #
  8. # Modifications       Removed the use of expr and replaced it by the let
  9. #                     command.
  10. #
  11. # ------------------------------------------------------------------------
  12. # This program is a free software, you can redistribute it and/or modify
  13. # it under the eterms of the GNU General Public Liscence as published by
  14. # the Free Software Foundation; either version 2 or (at your option) any
  15. # later version.
  16. #
  17. # This program is being distributed in the hope that it will be useful,
  18. # but WITHOUT ANY WARRANTY without even the implied warranty of
  19. # MERCHANTIBILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
  20. # Public Liscence for more details.
  21. # -------------------------------------------------------------------------
  22. # check for command line arguments
  23. if [ $# -ne 1 ]; then
  24.    echo "Usage: msinfo <partition name>"
  25.    exit 1
  26. fi
  27. # check whether the input name is a block device
  28. if [ ! -b $1 ]; then
  29.    echo "msinfo: $1 is not a block device"
  30.    exit 1
  31. fi
  32. # create two temporary files for use
  33. TMPFILE=`mktemp -q /tmp/$0.XXXXXX`
  34. if [ $? -ne 0 ]; then
  35.     echo "msinfo: Can't create temp file, exiting..."
  36.     exit 1
  37. fi
  38. TXTFILE=`mktemp -q /tmp/$0.XXXXXX`
  39. if [ $? -ne 0 ]; then
  40.    echo "msinfo: Can't create temp file, exiting..."
  41.    rm -f $TMPFILE
  42.    exit 1
  43. fi
  44. backtitle="`printf "%78s" "msinfo, Information about FAT16 filesystem -- Rahul Joshi"`"
  45. dialog --title "Boot sector of $1" --backtitle "$back_title" \
  46.        --infobox "\nAnalysing boot sector for $1\nPlease wait..."  14 60
  47. # truncate TXTFILE to zero length
  48. echo > $TXTFILE
  49. # get Formatting DOS version
  50. dd 2>/dev/null if=$1  bs=1 count=8 skip=3 | dd 2>/dev/null of=$TMPFILE
  51. printf >>$TXTFILE "%30s : %s\n" "Formatting DOS version" "`cat $TMPFILE`"
  52. # get file system
  53. dd 2>/dev/null if=$1  bs=1 count=8 skip=54 | dd 2>/dev/null of=$TMPFILE
  54. printf >>$TXTFILE "%30s : %s\n" "Filesystem" "`cat $TMPFILE`"
  55. # check if filesystem in a FAT16
  56. if [ "`cat $TMPFILE`" != "FAT16   " ]; then
  57.   dialog --title "Boot sector of $1" --backtitle "$back_title" \
  58.          --infobox  "\nCan't find a FAT16 filesystem on $1"  14 60
  59.   exit 2
  60. fi
  61. # get volume label in boot sector
  62. dd 2>/dev/null if=$1  bs=1 count=11 skip=43 | dd 2>/dev/null of=$TMPFILE
  63. printf >>$TXTFILE "%30s : %s\n" "Volume label in boot sector" "`cat $TMPFILE`"
  64. # get Sector size
  65. dd 2>/dev/null if=$1  bs=1 count=2 skip=11| od -An -tdS | dd 2>/dev/null of=$TMPFILE
  66. printf >>$TXTFILE "%30s : %d\n" "Sector size" `cat $TMPFILE`
  67. sector_size=`cat $TMPFILE`
  68. # get Reserved sectors
  69. dd 2>/dev/null if=$1  bs=1 count=2 skip=14| od -An -tdS | dd 2>/dev/null of=$TMPFILE
  70. printf >>$TXTFILE "%30s : %d\n" " Reserved sectors" `cat $TMPFILE`
  71. reserved_sectors=`cat $TMPFILE`
  72. # get FAT sectors
  73. dd 2>/dev/null if=$1  bs=1 count=1 skip=16| od -An -tdS | dd 2>/dev/null of=$TMPFILE
  74. fat_count=`cat $TMPFILE`
  75. dd 2>/dev/null if=$1  bs=1 count=2 skip=22| od -An -tdS | dd 2>/dev/null of=$TMPFILE
  76. sectors_per_fat=`cat $TMPFILE`
  77. # calculate the no of sectors allocated for FAT's
  78. let fat_sectors=fat_count*sectors_per_fat
  79. printf >>$TXTFILE "%30s : %u (%u x %u) \n" "FAT sectors" "$fat_sectors" \
  80.         "$fat_count" "$sectors_per_fat"
  81. # get root directory sectors
  82. dd 2>/dev/null if=$1  bs=1 count=2 skip=17| od -An -tdS | dd 2>/dev/null of=$TMPFILE
  83. root_sectors=`cat $TMPFILE`
  84. # calculate the no of sectors allocated for root directory
  85. let root_sectors=root_sectors*32/sector_size
  86. printf >>$TXTFILE "%30s : %u\n" "Root directory sectors" "$root_sectors"
  87. # get Total special sectors
  88. let total=reserved_sectors+fat_sectors+root_sectors
  89. printf >>$TXTFILE "%30s : %u\n" "Total special sectors" "$total"
  90. # display the information
  91. dialog --title "Boot sector of $1"  --backtitle "$back_title"  --msgbox "`cat
  92. $TXTFILE`" 14 60
  93. # delete temporary files
  94. rm -f $TMPFILE
  95. rm -f $TXTFILE
  96. # end of msinfo.sh
复制代码

看看老外是怎么写脚本的,值得我们学习借鉴;)
 楼主| 发表于 2003-5-14 02:10:21 | 显示全部楼层

如何编写函数

来自http://academic.strose.edu/academic/avitabile/cis422/linux10.htm

Functions
你可以在bash shell的环境下编写函数,有两种定义函数的格式:
  1. function functname()
  2. {
  3. shell commands
  4. }
  5. functname()
  6. {
  7. shell commands
  8. }
复制代码
下面是一个简单函数的脚本(ex1)示例:
  1. message()
  2. {
  3.   echo "message"
  4. }
  5. let i=1
  6. while [ $i -le 3 ]
  7. do
  8.   message
  9.   let i=$i+1
  10. done
复制代码
函数同样可以接受参数,$1存放第一个参数,$2存放第二个参数,$*存放输入参数的列表,...
  1. $ more ex2
  2. power()
  3. {
  4.   x=$1
  5.   y=$2
  6.   count=1
  7.   result=1
  8.   while [ $count -le $y ]
  9.   do
  10.     result=`expr ${result} \* $x`
  11.     count=`expr ${count} + 1`
  12.   done
  13.   echo $result
  14. }
  15. echo "Enter two numbers"
  16. read num1 num2
  17. echo -n "power is: "
  18. power $num1 $num2
复制代码
$ ex2
Enter two numbers
3 4
power is: 81

函数同样也可以返回值,使用return语句,在主程序(块)中,在调用函数之后保存返回状态$?的值.
  1. power()
  2. {
  3.   x=$1
  4.   y=$2
  5.   count=1
  6.   result=1
  7.   while [ $count -le $y ]
  8.   do
  9.     result=`expr ${result} \* $x`
  10.     count=`expr ${count} + 1`
  11.   done
  12.   return $result
  13. }
  14. echo "Enter two numbers"
  15. read num1 num2
  16. power $num1 $num2
  17. answer=$?
  18. echo "$num1 to $num2 is $answer"
复制代码

你也可以编写递归函数:
  1. power()
  2. {
  3.   x=$1
  4.   y=$2
  5.   if [ $y -eq 1 ]
  6.   then
  7.     return $x
  8.   else
  9.     y=`expr $y - 1`
  10.     power $x $y
  11.     result=`expr $? \* $x`
  12.     return $result
  13.   fi
  14. }
  15. echo "Enter two numbers"
  16. read num1 num2
  17. power $num1 $num2
  18. answer=$?
  19. echo "$num1 to $num2 is $answer"
复制代码
默认情况下,所有函数的变量都是全局变量.你可以用typeset去声明一个局部变量:
  1. easy()
  2. {
  3.   typeset a
  4.   a=`expr $1 + $2`
  5.   b=`expr $1 + $2`
  6.   echo "easy a is " $a
  7.   echo "easy b is " $b
  8. }
  9. a=10
  10. b=20
  11. easy $a $b
  12. echo "global a is " $a
  13. echo "global b is " $b
复制代码
Output:
easy a is  30
easy b is  30
global a is  10
global b is  30

如果要在脚本中多次使用函数,可以把它放在一个函数目录中,像一个普通文件一样,使用的时候把它放在脚本开始的地方:
. functionfile

$ more power
  1. power()
  2. {
  3.   x=$1
  4.   y=$2
  5.   if [ $y -eq 1 ]
  6.   then
  7.     return $x
  8.   else
  9.     y=`expr $y - 1`
  10.     power $x $y
  11.     result=`expr $? \* $x`
  12.     return $result
  13.   fi
  14. }
复制代码
$ more small
  1. . power
  2. echo "Enter two numbers:"
  3. read x y
  4. power $x $y
  5. result=$?
  6. echo "Answer is:" $result
复制代码
$ small.ksh
2 5
Answer is: 32
注:翻译的水平有限,望多包涵;)
 楼主| 发表于 2003-5-15 23:33:29 | 显示全部楼层

一个备份文件的脚本示例

来自:http://www.europe.redhat.com/
  1. #!/bin/bash
  2. # Backs up all files in current directory
  3. # modified within last 24 hours
  4. # in a tarred and gzipped file.
  5. if [ $# = 0 ]
  6. then
  7.   echo "Usage: `basename $0` filename"
  8.   exit 1
  9. fi  
  10. tar cvf - `find . -mtime -1 -type f -print` > $1.tar
  11. gzip $1.tar
  12. exit 0
复制代码
 楼主| 发表于 2003-5-17 23:48:50 | 显示全部楼层

删除文件与恢复文件

作者 pupilzeng
这一共有三个脚本,他们是一套的
1)del:删除文件,其实是把它移动到/trash/$user/下,不同的用户有不同的存放目录,同时用该目录下的.record文件记录文件原来的路径,删除时间,以备恢复只用。
2)recover:恢复文件,通过.record文件找到足够的信息,从而把它恢复
3)erase:这个是彻底的删除文件,从/trash/$user/目录下,相当于windows下的清空回收站。
为了安全,这个脚本是要在/trash/$user/目录下运行。
以下是这三个脚本
del:
  1. #!/bin/bash
  2. #move the file(s) to the /trash/~ instead of deleting.
  3. #Author: pupilzeng
  4. #E-mail: [email]shixinzeng@sjtu.edu.cn[/email]
  5. USER=`whoami`
  6. TRASH=/trash/$USER
  7. RECORD=/trash/$USER/.record #record file
  8. ORIG=`pwd`
  9. DATE=`date +%T---%Y/%m/%d`
  10. Usage ()
  11. {
  12.         echo "Usage: `basename $0` file(s)"
  13. }
  14. if [ "$1" = "-h" -o "$1" = "--help" ];then
  15.         Usage
  16.         exit 0
  17. fi
  18. if [ $# -le 0 ];then
  19.         Usage
  20.         exit 1
  21. fi
  22. if [ ! -d $TRASH ];then
  23.         mkdir -p $TRASH
  24. fi
  25. for i in "$@"
  26.         do
  27.         if [ -w "$i" ];then
  28.                 mv "$i" $TRASH
  29.                 if [ $? -ne 0 ];then
  30.                 echo "Something wrong occurred while delete file $i"
  31.                 #but now i won't exit,because there may be other files to be deleted!
  32.                 else
  33.                 #now write the record file
  34.                 #the lines below were modified!
  35.                 CURRENTDIR=$PWD #*
  36.                 cd `basename "$i"`
  37.                 echo -e "$PWD/`basename "$i"`\t\t$DATE ">>$RECORD
  38.                 cd $CURRENTDIR #* return to original working directory
  39.                  #The lines marked * can be omitted! For safety,they remain there.
  40.                #---------------------------------------------------------------
  41.                 fi
  42.                 else
  43.                         echo "You have not enough permission to delete $i!"
  44.         fi
  45.         done
  46. exit 0
复制代码

recover:
  1. #!/bin/bash
  2. #recover
  3. #Author: pupilzeng
  4. #E-mail: [email]shixinzeng@sjtu.edu.cn[/email]
  5. #To recover the removed file(s) by script myrm
  6. USER=`whoami`
  7. TRASH=/trash/$USER
  8. RECORD=$TRASH/.record
  9. TEMP=$TRASH/.temp
  10. Usage ()
  11. {
  12.         echo "Usage:`basename $0` file(s)"
  13. }
  14. if [ "$1" = "-h" -o "$1" = "--help" ];then
  15.         Usage
  16.         exit 0
  17. fi
  18. for i in "$@"
  19. do
  20.         DEST=`grep "$i" $RECORD |awk '{ print $1}'`
  21.         mv -f "$i" $DEST
  22.         
  23.         if [ $? -ne 0 ];then
  24.                 echo "Something occurred!"
  25.                 exit 1
  26.         else
  27.                 echo "Recovered $DEST"
  28.         #remove record from $RECORD
  29.         grep -v "$i" $RECORD >$TEMP
  30.         mv -f $TEMP $RECORD
  31.         fi
  32. done
  33. exit 0
复制代码

erase:
  1. #!/bin/bash
  2. #erase
  3. #Author: pupilzeng
  4. #E-mail: [email]shixinzeng@sjtu.edu.cn[/email]
  5. #erase the files in trash that you are sure they needn't at all.
  6. #for assurance,you should do it in /trash/user directory.
  7. Usage ()
  8. {
  9.    cat <<END
  10. Usage:`basename $0` [Option] file(s)
  11. Options:
  12.   -f  :don't prompt before erase files
  13. END
  14. }
  15. USER=`whoami`
  16. TRASH=/trash/$USER
  17. RECORD=$TRASH/.record
  18. FORCE=no
  19. TEMP=$TRASH/.temp
  20. if [ $# -lt 1 ]
  21. then
  22.         echo "Wrong parameters"
  23.         Usage
  24.         exit 1
  25. fi
  26. if [ $PWD != $TRASH ]
  27. then
  28.         echo "you should do it in $TRASH directory!"
  29.         exit 1
  30. fi
  31. if [ "$1" = "-h" -o "$1" = "--help" ]
  32. then
  33.         Usage
  34.         exit 0
  35. fi
  36. if [ "$1" = "-f" ];then
  37.         FORCE=yes
  38.         shift
  39. fi
  40. for i in "$@"
  41. do
  42.         ANS=no
  43.         if [ $FORCE = "yes" ];then
  44.                 rm -fr "$i"
  45.         else
  46.                 echo -n "Do you really wanna erase "$i"? Yes|[No]:"
  47.                 read ANS
  48.                 case $ANS in
  49.                 "Y"|"y"|"Yes"|"yes")
  50.                         rm -fr "$i"
  51.                         ;;
  52.                 *)
  53.                         continue
  54.                         ;;
  55.                 esac
  56.                
  57.         fi
  58.         if [ $? -eq 0 ];then
  59.         #now remove the records
  60.         grep -v "$i" $RECORD >$TEMP
  61.         mv -f $TEMP $RECORD
  62.         fi
  63. done
  64. exit 0
复制代码
 楼主| 发表于 2003-5-20 22:39:51 | 显示全部楼层

用shell脚本编写的进度条

转自:www.chinaunix.net
drawper ()
{
_per=`expr $1 \* 100 / $2`
case `expr $_per / 4 % 4` in
0) _char="|" ;;
1) _char="/" ;;
2) _char="-" ;;
3) _char="\\" ;;
esac
printf "\r$_char $_per%%"
if [ $1 -eq $2 ];then
printf "\n"
fi
}

i=1
while [ $i -le 100 ]
do
drawper $i 100
i=`expr $i + 1`
done
看看人家是怎么玩shell的,值得学习!;)
 楼主| 发表于 2003-5-23 00:20:27 | 显示全部楼层

一个加密文本文件的脚本

作者:javalee
利用vim中对key=的设置,可以达到加密文本文件的目的,
  1. #!/bin/ksh
  2. # 利用vi中的key=命令,对文本进行加密处理.
  3. #scriptname:jmfile
  4. (($# != 2)) && { print "格式: jmfile password filename";exit 1; }
  5. vim -e -s -c ":set key=$1" -c ":wq" $2
  6. print "文件$2已经加密!"
复制代码
如:
javalee//home/javalee/lx>echo aaaaa>tmp
javalee//home/javalee/lx>cat tmp
aaaaa
javalee//home/javalee/lx>jmfile 123 tmp
文件tmp已经加密!
javalee//home/javalee/lx>cat tmp
VimCrypt~01!!x蹥o鮦avalee//home/javalee/lx>    //加密后的文件用cat显示全是乱字符.
javalee//home/javalee/lx>vi tmp  //编辑
in vim...
输入密码:***
如果密码正确就可以编辑tmp文件.
关于VIM的使用,请vim --help
发表于 2003-5-24 19:31:19 | 显示全部楼层

一个简单的notify程序

作者:hdw1978
if [ $1 = 0 ]; then
        esdplay /home/hdw1978/tada.wav > /dev/null
else
        esdplay /home/hdw1978/chord.wav > /dev/null
fi

用法:
在make一个大软件的时候可以用make;notify, 然后你就可以去忙别的事了,make完成后会播放一个音效通知你。而且还可以附带弹出一个通知窗口,以免临时走开没听到(不过我没有做)

还可以用在其它耗时较长又不需要一直观察的任务后面

很简单,但是我经常用
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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