首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > 编程 >

Shell编程基础 part 二/2

2013-11-08 
Shell编程基础 part 2/26 命令行参数特殊变量$*, $1, $2, ...$9包含了用户从命令行输入的参数 简单的命令

Shell编程基础 part 2/2

6 命令行参数

特殊变量$*, $1, $2, ...$9包含了用户从命令行输入的参数; 简单的命令行语法(强制性参数和查看帮助的-h选项); 在编写复杂程序时, 可能需要更多的自定义选项; 通常的惯例是在所有可选的参数之前添上一个减号 - , 后面跟参数值(文件名);

e.g. 实现对输入参数的分析: case

123456789101112131415161718192021222324help(){   cat << HELP   This is a generic command line parser demo.   USAGE EXAMPLE: cmdparser -l hello -f -- -somefile1 somefile2HELP   exit 0} while [ -n "$1" ]; docase "$1" in   -h) help;shift 1;; # function help is called   -f) opt_f=1;shift 1;; # variable opt_f is set   -l) opt_l=$2;shift 2;; # -l takes an argument -> shift by 2   --) shift;break;; # end of options   -*) echo "error: no such option $1. -h for help";exit 1;;   *) break;;esacdone echo "opt_f is $opt_f"echo "opt_l is $opt_l"echo "first arg is $1"echo "2nd arg is $2"

>运行脚本: cmdparser -l hello -f -- -somefile1 somefile2; 

>输出: opt_f is 1; opt_l is hello; first arg is -somefile1; 2nd arg is somefile2;

>脚本首先在所有输入命令行参数中进行循环, 将输入参数与case表达式进行比较, 如果匹配则配置一个变量并且移除该参数; 根据unix惯例, 首先输入的应该是包含减号的参数;


7 Shell脚本示例

一般编程步骤

任何优秀的脚本都应该有帮助和输入参数; 写一个框架脚本framework.sh, 包含大多数脚本需要的框架结构是一个好主意;

这样, 在开始编写新脚本时, 可以先执行以下命令: cp framework.sh myscript ; 然后再插入自己的函数; [节省时间, 规范代码]


二进制到十进制的转换

脚本b2d将二进制数转换为相应的十进制, 利用expr命令进行数学运算;

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091#!/bin/bash# vim: set sw=4 ts=4 et:help(){   cat << HELP b2d -- convert binary to decimal USAGE: b2d [-h] binarynum OPTIONS: -h help text EXAMPLE: b2d 111010will return 58HELP   exit 0} error(){   # print an error and exit   echo "$1"   exit 1} lastchar(){   # return the last character of a string in $rval   if [ -z "$1" ]; then      # empty string      rval=""      return   fi   # wc puts some space behind the output this is why we need sed:   numofchar=`echo -n "$1" sed 's/ //g' wc -c `   # now cut out the last char   rval=`echo -n "$1" cut -b $numofchar`} chop(){   # remove the last character in string and return it in $rval   if [ -z "$1" ]; then      # empty string      rval=""      return   fi   # wc puts some space behind the output this is why we need sed:   numofchar=`echo -n "$1" wc -c | sed 's/ //g' `   if "$numofchar" "1" ]; then      # only one char in string      rval=""      return   fi   numofcharminus1=`expr $numofchar "-" 1`   # now cut all but the last char:   rval=`echo -n "$1" cut -b -$numofcharminus1`   #原来的 rval=`echo -n "$1" | cut -b 0-${numofcharminus1}`运行时出错.   #原因是cut从1开始计数,应该是cut -b 1-${numofcharminus1}} while [ -n "$1" ]; docase $1 in   -h) help;shift 1;; # function help is called   --) shift;break;; # end of options   -*) error "error: no such option $1. -h for help";;   *) break;;esacdone # The main programsum=0weight=1# one arg must be given:[ -z "$1" ] && helpbinnum="$1"binnumorig="$1" while [ -n "$binnum" ]; do   lastchar "$binnum"   if "$rval" "1" ]; then      sum=`expr "$weight" "+" "$sum"`   fi   # remove the last position in $binnum   chop "$binnum"   binnum="$rval"   weight=`expr "$weight" "*" 2`done echo "binary $binnumorig is decimal $sum"#

>使用的算法是十进制和二进制数权值(1 2 4 8 16...), e.g. 二进制10 -> 0 * 1 + 1 * 2 = 2;

>lastchar函数得到单个的二进制数, 该函数使用wc -c计算字符个数, 然后用cut命令取出末尾一个字符; chop函数的功能是移除最后一个字符;


文件循环拷贝

e.g. 将所有发出的邮件保存到一个文件中; 过了一段时间后这个文件可能会变很大以至于文件访问速度变慢; 脚本rotatefile可以重命名邮件保存文件为outmail.1, 把原来的outmail.1变成outmail.2等等...

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162#!/bin/bash# vim: set sw=4 ts=4 et: ver="0.1"help(){   cat << HELP   rotatefile -- rotate the file name   USAGE: rotatefile [-h] filename   OPTIONS: -h help text   EXAMPLE: rotatefile out    This will e.g rename out.2 to out.3, out.1 to out.2, out to out.1[BR]   and create an empty out-file    The max number is 10    version $ver HELP    exit 0} error(){   echo "$1"   exit 1} while [ -n "$1" ]; do   case $1 in      -h) help;shift 1;;      --) break;;      -*) echo "error: no such option $1. -h for help";exit 1;;      *) break;;   esacdone # input check:if [ -z "$1" ] ; then   error "ERROR: you must specify a file, use -h for help"fi filen="$1"# rename any .1 , .2 etc file:for in 9 8 7 6 5 4 3 2 1; do   if [ -f "$filen.$n" ]; then      p=`expr $n + 1`      echo "mv $filen.$n $filen.$p"      mv $filen.$n $filen.$p   fidone # rename the original file:if [ -f "$filen" ]; then   echo "mv $filen $filen.1"   mv $filen $filen.1fi echo touch $filentouch $filen

>检测到用户提供了一个文件名之后, 先进行一个9到1的循环, 文件名.9 重命名为 文件名.10, .8 -> .9 ... 循环结束后把原始文件命名为 文件名.1 ,同时创建一个和原始文件同名的空文件(touch $filen);


脚本调试

最简单的调试方法是使用echo命令; [print流派...] 可以在任何怀疑会出错的地方用echo打印变量值, 大部分shell程序员花费80%时间用于调试; shell脚本的好处在于无需重新编译, 插入echo命令也不需要多少时间;

shell也有调试模式, 如果脚本strangescript出错, 可以使用:

1sh -x strangescript

>执行脚本, 同时显示所有变量的值; [每一步输出]

 shell还有不执行脚本只检查语法的模式:

1sh -n your_script

>这个命令会返回所有语法错误;

---The End---

refer to http://wiki.ubuntu.com.cn/Shell%E7%BC%96%E7%A8%8B%E5%9F%BA%E7%A1%80

热点排行