个人工具
登录
查看“Shell编程基础”的源代码 - Ubuntu中文
页面
讨论
查看源代码
历史
搜索
导航
首页
最近更改
随机页面
页面分类
帮助
编辑
编辑指南
沙盒
新闻动态
字词处理
工具
链入页面
相关更改
特殊页面
页面信息
查看“Shell编程基础”的源代码
来自Ubuntu中文
←
Shell编程基础
跳转至:
导航
,
搜索
因为以下原因,你没有权限编辑本页:
您所请求的操作仅限于该用户组的用户使用:
用户
您可以查看与复制此页面的源代码。
== Shell脚本示例== === 一般编程步骤=== 现在我们来讨论编写一个脚本的一般步骤。任何优秀的脚本都应该具有帮助和输入参数。写一个框架脚本(framework.sh),该脚本包含了大多数脚本需要的框架结构,是一个非常不错的主意。这样一来,当我们开始编写新脚本时,可以先执行如下命令: <source lang="bash"> cp framework.sh myscript </source> 然后再插入自己的函数。 让我们来看看如下两个示例。 === 二进制到十进制的转换 === 脚本 b2d 将二进制数 (比如 1101) 转换为相应的十进制数。这也是一个用expr命令进行数学运算的例子: <source lang="bash"> #!/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 111010 will return 58 HELP 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 ` #sed 's/ //g' 所有空白去掉 sed 's/ /\t/g' 所有空白用t代替 # now cut out the last char 抓取第numofchar个字节 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" ]; do case $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;; esac done # The main program sum=0 weight=1 # one arg must be given: [ -z "$1" ] && help binnum="$1" binnumorig="$1" while [ -n "$binnum" ]; do lastchar "$binnum" if [ "$rval" = "1" ]; then sum=`expr "$weight" "+" "$sum"` # $expr 10 + 10 20 expr提示是计算操作 fi # remove the last position in $binnum chop "$binnum" binnum="$rval" weight=`expr "$weight" "*" 2` done echo "binary $binnumorig is decimal $sum" # </source> 该脚本使用的算法是利用十进制和二进制数权值 (1,2,4,8,16,..),比如二进制"10"可以这样转换成十进制: <source lang="bash"> 0 * 1 + 1 * 2 = 2 </source> 为了得到单个的二进制数我们是用了lastchar 函数。该函数使用wc –c计算字符个数,然后使用cut命令取出末尾一个字符。Chop函数的功能则是移除最后一个字符。 但是还记得前面怎么说的吗?进制转换哪需要这么麻烦: <source lang="bash"> #!/bin/bash while read -p 'input a binary...' num; do if [[ $num == *[!01]* ]]; then echo "含有 0 1 之外的字符" fi echo "$((0x$num))" # 在 num 头上糊一个 0x 然后跑数学计算——就完事了! printf "%d\n" "0x$num" # printf 也可以凑热闹啊 done </source> 如果你喜欢自己算的话,其实也可以从左到右来(反正数学计算不要有事没事玩 expr 啦): <source lang="bash">#!/bin/bash # 人人皆知的 Horner 规则 value=0 echo "写一堆 1 0 完了回车" while read -n 1 char; do case $char in (0|1) ;; # 好 ('') break;; # 没了 (*) echo "你说啥?"; break;; esac ((value *= 2)) ((value += char)) done echo "$value"</source> === 文件循环移动 === 你可能有这样的需求并一直都这么做:将所有发出邮件保存到一个文件中。但是过了几个月之后,这个文件可能会变得很大以至于该文件的访问速度变慢;下面的脚本 rotatefile 可以解决这个问题。这个脚本可以重命名邮件保存文件(假设为outmail)为outmail.1,而原来的outmail.1就变成了 outmail.2 等等... <source lang="bash"> #!/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 and create an empty out-file version $ver HELP exit 0 } if [[ $1 == '-h' || $1 == '' ]]; then help fi filename=$1 # 我们先找到最大的数字再说。 max=0 while [ -f "$filename.$((++max))" ]; do : # 什么都不用做,我们已经顺手用 ++max 自增了 max 了。 done # 然后从最大的一路重命名下来。 for ((i=max; i>0; i--)); do # 数字加个 1,好给前一个让位子。 mv "$filename.$i" "$filename.$((i+1))" done # 最后我们点名要重命名的: if [ -f "$filename" ]; then mv "$filename" "$filename.1" fi # 重新创建一下。 : > "$filename" </source>。
返回至
Shell编程基础
。