linux练习

shell脚本例子集锦(习题总结)
练习一:写一个脚本
       1.设定变量FILE的值为/etc/passwd
       2.依次向/etc/passwd中的每个用户问好,并且说出对方的ID是什么
        形如:(提示:LINE=`wc -l /etc/passwd | cut -d" " -f1`)
         Hello,root,your UID is 0.
       3.统计一个有多少个用户
     答案一:#!/bin/bash
           file="/etc/passwd"
           LINES=`wc -l $file | cut -d" " -f1`
           for I in `seq 1 $LINES`;do
           userid=`head -$I $file | tail -1 |cut -d: -f3`
           username=`head -$I $file | tail -1 |cut -d: -f1`
           echo "hello $username,your UID is $userid"
           done
           echo "there are $LINES users"
     答案二:#!/bin/bash
           file=/etc/passwd
           let num=0
           for I in `cat $file`;do
           username=`echo "$I" | cut -d: -f1`
           userid=`echo "$I" | cut -d: -f3`
           echo "Hello,$username,your UID is $userid"
           num=$[$num+1]
           done
           echo "there are $num users"
练习二:写一个脚本
      1.切换工作目录至/var
      2.依次向/var目录中的每个文件或子目录问好,形如:
        (提示:for FILE in /var/*;或for FILE in `ls /var`;)
        Hello,log
      3.统计/var目录下共有多个文件,并显示出来
  答案:#!/bin/bash
         cd /var
         let num=0
         for I in `ls /var/*`;do
         echo "hello $I"
         num=$[$num+1]
         done
         echo "the number of files is $num"
练习三:写一个脚本
      1.设定变量file的值为/etc/passwd
      2.使用循环读取文件/etc/passwd的第2,4,6,10,13,15行,并显示其内容
      3.把这些行保存至/tmp/mypasswd文件中
  答案:#!/bin/bash
       file="/etc/passwd"
       for I in 2 4 6 10 13 15;do
       exec 3>/tmp/mypasswd
       line=`head -$I $file | tail -1`
       echo "$line"
       echo "$line" >&3
       exec 3>&-
       done
练习四:写一个脚本
       传递两个整数给脚本,让脚本分别计算并显示这两个整数的和,差,积,商
        答案如下:vim test.sh
                   #!/bin/bash
                    echo "first number $1"  (表示输出第一个数)
                    echo "second number $2" (表示输出第二个数)
                    echo " $(($1+$2))"      (输出两数之和)
                    echo "$[$1-$2]"         (输出两数之差)
                    echo "$[$1*$2]"         (输出两数之积)
                    echo "$[$1/$2]"         (输出两数之商)
                    :wq                    (表示保存并退出vi编辑器)
                    chmod +x test.sh       (给test.sh执行的权限)
                    ./test.sh 2 3          (传递两个参数并执行脚本     
作业一:写一个脚本:
       1.创建目录/tmp/scripts
       2.切换工作目录至此目录中
       3.复制/etc/pam.d目录至当前目录,并重命名为test
       4.将当前目录的test及其里面的文件和子目录的属主改为redhat
       5.将test及其子目录中的文件的其它用户的权限改为没有任何权限
   答案:
       #!/bin/bash
       mkdir -v /tmp/scripts
       cd /tmp/scripts
       cp -r /etc/pam.d ./test
       chown -R redhat ./test
       chmod -R o=--- ./test
作业二:写一个脚本
       1.显示当前系统日期和时间,而后创建目录/tmp/lstest
       2.切换工作目录至/tmp/lstest
       3.创建目录a1d,b56e,6test
       4.创建空文件xy,x2y,732
       5.列出当前目录下以a,x或者6开头的文件或目录
       6.列出当前目录下以字母开头,后跟一个任意数字,而后跟任意长度字符的文件或目录
   答案:
       #!/bin/bash
       date
       mkdir -pv /tmp/lstest
       cd /tmp/lstest
       mkdir a1d b56e 6test
       touch xy x2y 732
       ls [ax6]*
       ls [[:alpha:]][[:digit:]]*
            
作业三:写一个脚本
        添加10个用户user1到user10,但要求只有用户不存在的情况下才能添加
  答案:
       #!/bin/bash
       for I in `seq 1 10`;do
       cut -d: -f1 /etc/passwd |grep "user$I" 2>>/tmp/etc.err || useradd user$I
       done
作业四:写一个脚本
       通过ping命令测试192.168.0.151到192.168.0.254之间的所有主机是否在线
       如果在线,就显示“ip is up”
       如果不在线,就显示“ip is down”
      答案: #!/bin/bash
       for I in `seq 151 254`;do
       ping -c1 -w1 192.168.0.$I &>/dev/null && echo "192.168.0.$I is up" ||        echo "192.168.0.$I is down"
       done
例题:
shell1.sh  显示日期和时间。

#!/bin/bash
echo “current time is `date`”       //date要加反引号

shell2.sh  显示文件名,并显示位置参数(执行时带一个参数)。(①$0是一个特殊的变量,它的内容是当前这个shell程序的文件名;②$1是一个位置参数,位置参数之间用空格分隔,shell取第一个位置参数替换程序文件中的$1,第二个替换$2,依次类推。)

#!/bin/bash
echo “the program name is $0”  //$0是一个特殊的变数
echo “the first para is $1”     //$1是一个位置参数
echo “the program exit”      //执行时带一个参数 如./shell2.sh  abcd

shell3.sh  判断并显示位置参数

        #!/bin/bash
        if [ -d “$1”];then
        echo “$1 is directory ,existed”
        else
        echo “$1 does not exist ,now create it”
        mkdir $1
        echo “$1 is created”
        fi   //执行时带一个参数

shell4.sh   问候用户

   #!/bin/bash
    user=`whoami` 
   case $user in
    teacher)
    echo “hello teacher”;;
    root)
    echo “hello root”;;
    *)
    echo “hello $user,welcome”
    esac

1、    求1+2+3+...+100的和是?

#!/bin/bash
SUM=0
I=0
while [ $I -le 100 ]
do
    SUM=$((SUM+I))
    I=$((I+1))
done
echo "由1+2+3+...+100的和是:$SUM"

2、(基训十一)  在根目录下有四个文件m1.txt,m2.txt,m3.txt,m4.txt,用Shell编程,实现自动创建m1,m2,m3,m4四个目录,并将m1.txt,m2.txt,m3.txt,m4.txt四个文件分别拷贝到各自相应的目录下。

#!/bin/bash
cd /
touch m1.txt m2.txt m3.txt m4.txt
I=1 
while [ $I -le 4 ]
do 
   mkdir m$I
   cp m$I.txt m$I
   I=$((I+1))
done

3、(基训十二)  编写一个名为myfirstshell.sh的脚本,它包括以下内容。a) 包含一段注释,列出您的姓名、脚本的名称和编写这个脚本的目的。
b) 问候用户。
c) 显示日期和时间。
d) 显示这个月的日历。
e) 显示您的机器名。
f) 显示当前这个操作系统的名称和版本。
g) 显示父目录中的所有文件的列表。
h) 显示root正在运行的所有进程。
i) 显示变量TERM、PATH和HOME的值。
j) 显示磁盘使用情况。
k) 用id命令打印出您的组ID。
m) 跟用户说“Good bye”

#!/bin/bash
# 09嵌入 5号 贾德进 myfirstshell.sh shell的简单编程
user=`whoami`
case $user in
root)
echo "hello root";;
teacher)
echo "hello teacher";;
*)
echo "hello $user,welcome"
esac
echo "日期和时间: `date`"
echo "本月的日历: `cal`"
echo "本机的机器名:`uname -n`"
echo "当前这个操作系统的名称和版本:`uname -s;uname -r`"
echo "父目录中的所有文件的列表:`ls ../`"
echo "root正在运行的所有进程:` ps -u root`"
echo "变数TERM的值:$TERM"
echo "变数PATH的值:$PATH"
echo "变数HOME的值:$HOME"
echo "磁盘的使用情况:`df`"
echo "用id命令打印出你的组ID:`id -g`"
echo "Good bye!"

4、(基训十三)  设计一个Shell程序,在/userdata目录下建立50个目录,即user1~user50,并设置每个目录的权限为 rwxr-xr—

#!/bin/bash
cd /userdata
I=1
while [ $I -le 50 ]
do 
   mkdir -p userdata/user$I 
   chmod o-x user$I 
   I=$((I+1))
done

5、(基训十四)  编写shell程序,实现自动删除50个用户账号的功能。账号名为stud1至stud50。

#!/bin/bash
cd /userdata
I=1
while [ $I -le 50 ]
do  
mkdir -p userdata/user$I  
chmod o-x user$I
I=$((I+1))
done

6、(基训十四)  设计一个shell程序,备份并压缩/etc目录的所有内容,存放在/root/bak目录里,且文件名为如下形式yymmdd_etc,yy为年,mm为月,dd为日。

#!/bin/bash
DIRNAME=`ls |root|grep bak `
if [-z $DIRNAME ]; then  
   mkdir /root/bak   
cd /root/bak
fi
YY=`date + %y`
MM=`date + %m`
DD=`date + %d`tar czvf ${YY}${MM}${DD}_etc.gz /etc
echo "etc bak finshied"

7、(基训十四)  某系统管理员需每天做一定的重复工作,请按照下列要求,编制一个解决方案:
(1)在下午4 :50删除/abc目录下的全部子目录和全部文件;
(2)下午5:50将/data目录下的所有目录和文件归档并压缩为文件:backup.tar.gz;
(3)在下午5:55将IDE接口的第二个逻辑分区卸载。

// 采用: vi  pram.cron

#(1) 在下午4:50删除/abc目录下的全部子目录和全部文件;
50 16 *** rm -rf /abc/*
#(2) 下午5:50将/data目录下的所有目录和文件归档并压缩为文件:backup.tar.gz;
50 17 *** tar czvf back.tar.gz /data
#(3) 在下午5:55将IDE接口的第二个逻辑分区卸载.
55 17 *** umount /dev/hda6

// 执行:crontab pram.cron
==========================================================
设计一个Shell程序,在/userdata目录下建立50个目录,即user1~user50,并设置每个目录的权限,其中其他用户的权限为:读;文件所有者的权限为:读、写、执行;文件所有者所在组的权限为:读、执行。

程序实现及注释如下:

#! /bin/bash
#adddir.sh
i=1
#while循环
while [ $i -le 50 ]
do
#利用 test命令 [ -d /userdata ]:判断/userdata是否存在,如果存在直接创建子目录,不#存在先创建/userdata再创建子目录。

if [ -d /userdata ]
then
#mkdir -p的意思是:无论父目录/userdata存在与否,都会创建/userdata/user$i
 mkdir -p /userdata/user$i 
else
 mkdir  /userdata
 mkdir -p /userdata/user$i
fi
#根据题目的意思:/userdata/user$i应该是具有754权限,所以利用chmod赋权限。

chmod  754 /userdata/user$i
i=$(($i+1))
done

函数in_path:判断传入文件是否可执行,若可执行(且存在)返回0, 否则返回1;
分析:为测试传入文件是否在PATH所有的目录中,需取得PATH中的每个路径,可用循环,但需要设定环境中的分隔符(借助环境变量IFS)为 PATH中的分隔符冒号”:”
  
注:$IFS 输入分隔符. 当shell读取输入数据的时候,会把一组字符看做是单词之间的分隔字符,它们通常是空格,制表符,和换行符.
函数调用方式为 : in_path filename
in_path()
{
cmd=$1                          # $1为函数的参数1,以此类推
retval=1                                       #定义返回值变量
oldIFS=$IFS            IFS=:                #设置新的IFS,并保存原来的以恢复使用
for  directory in $PATH            #for循环结构二: for – in
do
        if [ -x directory/$cmd ] ; then           #if条件语句之 同行表示 以分号隔开
            retval=0                              # -x   判断文件有是否有可执行权限
        done
    done
    IFS=$oldIFS                                           #恢复原来IFS,  
    return retval
}
注:1.函数的结构, 没有形参
2.变量的引用需要符号$,而变量的定义或赋值则不需要。
3.赋值要无间隙, 条件要间隙
改进: 1.将路径、分隔符均作为函数的参数传入,应用得到扩展。

补充,in_path函数不能对绝对路径的文件处理,需写个函数对这一情况单独处理
checkForCmdInPath()
{
    var=$1
#首先判断传入的非空串是否为绝对路径,即检测第一个字符是不是”/”,如果是,直接测 –x
     if [ $var != “” ] ; then           # 条件等价于  -n $var
        if [ “${var%${var#?}}” = ‘/’ ] ; then     #等价于 $(echo $var | cut -c1) 
            if [ ! -x $var ] ; then
                return 1       #not found or not executable
            fi
        elif ! inpath $var ; then          
            return 2          #not found in PATH
        fi
    fi
}
注:此函数让人一头雾水,详解如下:
1)    表达式${var%${var#?}}作匹配用,分解为 ${var%expr}  ${var#expr} ,expr为正则表达式(? 匹配单一字符)
       后者(带#的)返回 expr与var匹配成功位置之后的所有内容,此处为var中第一字符之后的所有。
       前者(带%的)返回 expr与var匹配成功位置之前的所有内容,此处应为 var的第一个字符。
             等价于 $(echo $var | cut c1)   即取第一字符。
            等价于 ${var:beginpos:size} 中beginpos=0,size=1时的结果。
      var的符号放在外面了,假设$var为$1,则表达式表示为 ${1%${1#?}}
2)    关于if的条件判断与C语言中的理解不一致,反映在上述的 elif语句中的条件。理解如下:
shell中的if条件可以是 表达式(需加方括号[]),另外还可以是命令或函数(不需方括号), 当命令执行成功时会后继执行具体操作,经测试,C语言中所说的true在shell中 用0表示,即if 0,才执行then,因为linux下的程序实现都是当返回0时表执行成功。
3)    若函数中没有返回值,则它默认返回0,表执行成功。
 函数的编写若遵从以上的原则, 则对条件的理解 依旧像C语言中的TRUE,FALSE一样理解


==============  完善程序代码 =====================================
#!/bin/bash
in_path()
...   # 函数实现区域 处理不路径                 返回0表找到、可执行, 否则返回1

###############################

checkForCmdInPath()
...   # 函数实现区域      处理带路径和不带路径的       返回1表没找到或不可执行,返回2表没找到。默认0表找到
 
################################
 #####  代码执行起始位置   ##############
 if [ $# -nq 1 ] ; then
    echo “Usage: $0 command”                        #$0 表此执行文件 (具体内容 以 执行此文件时的输入串为准)
    exit 0
 fi

# 调用函数,并经第一个参数传给函数
checkForCmdInpath $1

# 对函数返回的结果进行判断        $?  为函数的返回值,
case $? in                                                              # case 控制结构的格式,注意红色部分。
    0)    echo “found in PATH”    ;;
    1)    echo “not found or not executable”    ;;
    2)    echo “not found”    ;;                  #   *)  ;;         类似于C语言中的 default
======================================================================== 
2.写一个脚本,检测用户输入串的合法性, 要求串由大小写字母、数字组成,无标点、特殊符号、空格。
思路:将输入的串中 非字母数字的内容删除或替换为空后若和原来输入的相同则合法,否则不合法。
isvalidAlphaNum()
{
    compressed=”$(echo $1 | sed 's/[^[:alnum:]]//g')”      #替换不合要求字符为空
    if [ “$compressed” != “$1” ] ; then
        return 1    #  not valide
    else
        return 0                     #  valide
    fi
}

注: 1.关于引用变量时是否需要双引号的说明
       如果只是输出,可以不用双引号
       如果变量值代的内容中无空格,表达,特殊符号,在引用时可以不需要双引号,反之,最好带双引号,否则在变量处理时很有可
能会出现“参数过多”等莫名其妙的错误信息。
     2.关于匹配处理,sed是单行编辑程序。  sed ‘s/str1/str2/g’  file    将文件file中每行内str1替换为str2
       [[:alnum:]]表示所有字母和数字中的任一个字符。若只是[:alnum:]则表示 方括号中的任一个字符。
       [^[:alnum:]] 表除了所有字母数字外的任一字符。

如果是直接向脚本传字符串,则带空格的字串会被脚本自行分解为多个参数,所以可采用从标准输入读取的方式获得字串。
==============  完善程序代码 =====================================
#!/bin/bash

isvalidAlphaNum()
  ...                      #函数体,判断字串的合法性

echo  -n “Enter input:”            # -n 强制不换行
read  input                    #读取内容存到input中, 无 $ 符号

if ! isvalidAlphaNum “&input” ; then          #加引号,否则可能会出错。
    echo “invalide”
    exit 1
else
    echo “valide”
fi
exit 0
===============================================================


 
3.输入一个 “month day year”格式的日期串,程序将处理” month”为 其英文单词的前三个字母,第一个字母大写,其余的小写。
思路:首先判断month是数字、还是单词,若是数字,则可查“数字—month”映射表(自定义case结构);若是单词,则取前三个字母,并格式化。
函数monthnoToName() 将month数字转换为month名
monthnoToName()         
{
    case $1 in         
    1 ) month="Jan"    ;;  2 ) month="Feb"    ;;
    3 ) month="Mar"    ;;  4 ) month="Apr"    ;;
    5 ) month="May"    ;;  6 ) month="Jun"    ;;
    7 ) month="Jul"    ;;  8 ) month="Aug"    ;;
    9 ) month="Sep"    ;;  10) month="Oct"    ;;
    11) month="Nov"    ;;  12) month="Dec"    ;;
    * ) echo "$0: Unknown numeric month value $1" >&2; exit 1    # default,
   esac        # 
   return 0
}

假设通过传三个参数到脚本——month day year
----------  实现代码  ------------------------------
#!/bin/bash
if [ $# -ne 3 ] ; then                                 #若参数个数不为3,则有误
    echo “Usage: $0 month day year”
    exit 1
fi

#判断参数1是数字还是单词,方法 替换串中所有数字,若结果为空,则为数字,否则为单词。
if [ -n $(echo $1 | sed ‘s/[[:digit:]]//g’) ]    #  -n 检测串是为空
then
    monthnoToName $1                        # 数字
else
    # 取第一个字母并将其变为大写,再将结果与取出的第二三字母组合
    month=”$(echo $1 | cut –c1 | tr '[:lower:]' '[:upper:]')“
    month=”$month$(echo $1 | cut -c2-3 | tr '[:upper:]' '[:lower:]')”
fi

echo $month $2 $3            # 输出结果
exit 0
-------------------------------------------------

注:1.外围可以使用函数中定义的变量,如函数monthnoToName中定义的month变量,最后echo会用到它。
    2. 多管道(|)的使用
    3. month变量的合并,  $var$var
    4. tr  SET1 SET2  转换/删除/替换 命令, 将默认 将SET1 替换为 SET2
         tr 默认从标准输入读取,处理后 写入 标准输出。
    5. cut –c2-3  file    取文件每行第2,3字母。
扩展: 处理MM/DD/YYYY or MM-DD-YYYY 的形式。在判断三个参数前执行命令
set -- $(echo $1 | sed 's/[\/\-]/ /g') 。set 的 –- 命令可以将其后的参数赋予 位置参数($1,$2,...) 。
         链接 set 指令 用法
 
4. 格式化输出 大数字,使输出结果更容易让人知道该输出数字的数量级。
默认用逗号分隔整数部分,用点号分隔整数与小数部分,当然用户也可以使用 –d 指定整数的分隔符,用-t指定
整数与小数部分的分隔符。
算法: 1232342142.423023  ==> 默认:1,232,342,142.423023
(1)首先分开整数部分integer 和小数部分decimal,  sed –d. -f1 和 sed –d. -f2  分别取两部分。
(2)整数部分的处理: 
当作数字来处理         %运算  /运算
    1)每次取整数低三位,长度小于3就补前缀0(避免出现漏0情况,例如低三位为003时,取后便为值3)
    2)将此次得到的三位与上一次得到的三位用分隔符(如果没有指定就默认)组合起来。
    3)整数去掉低三位,继续操作1)。当此整数小于等于999就不再继续。
      当字串来处理:
    1)每次取低三位,      cut –c $((${#str} - 2))-${#str}    
        ${#str} 为str的长度,必须为大括号。
        $(( )) 的内部为str长度-2,代表倒数低三个字符。因为内部是减法,所有此为双小括号。
    2)原串每次都要裁掉尾部三个字符,每次取到的字串的长度为循环判断条件。

函数 nicenumber()作如上处理
nicenumber()            # 传入 integer.decimal 如2000023.2, 32232332等
{
    # 分别取 整数部分和小数部分
    integer=$(echo $1 | cut –d. –f1)
decimal=$(echo $1 ! cut –d. –f2)

# 判断小数部分是否存在,因为这涉及连接整数和小数的连接符问题
# 设DD 为 整数和小数之间分隔符,默认为 .
if [ –n $decimal ] ; then                    #若非空,即有小数部分。
    #以下四句可用一句表示:result=”${DD:=”.”}$remainder$result”
    if [ -z $DD ]; then                           #判断用户是否自定义整数与分隔符,若空
        DD=.
    fi
    result=$DD$decimal                         # 在小数部分前加 分隔符。
fi

thousand=$integer
while [ thousand –gt 999 ]                            
do
    remainder=$((thousand%1000))            
    while [ ${#remainder} –lt 3 ];do            #${#remainder} 为remainder串的长度
        remainder=0$remainder                    # 避免remainder为00x时的丢0情况。
    done

    thousand=$(($thousand/1000))
    #以下四句可用一句表示:result=”${TD:=”,”}$remainder$result”
    #  上面蓝色部分表:若TD非空则返回TD,否则将”,”赋给TD.
    if [ –z $TD ] ; then                    # 判断用户是否自定义整数分隔符, 若 空
        TD=,
    fi
    result=”$TD$remainder$result”            # 与分隔符合成串。 注意顺序
done
if [ –n $thousand ]; then            # 若 非空
result=”$thousand$result”
        elif [ ${result%${result#?}} = “$TD” ]; then
            result=”${result#?}”
        fi
        echo $result
}
    
    脚本标志参数处理命令:     getopts  “”  var
        带两个参数,第一个参数为带解析的 参数标志序列串(如-f,-c等), 以冒号(:)分隔各标志,且以冒号:结束
        第二个参数为:变量,每执行一次存放 参数标志序列串中的一个标志字符
        返回值:未解析结束返回0,解析结束返回1
        涉及的内定变量:$OPTARG    每次解析标志对应的参数值 便默认存放在此变量内。
                        $OPTIND    当各标志处理无误情况下,该数值指示当前用到的最大位置参数($#)。  
                            此值使用容易出错(若参数的判断不完善时), 还不如用 $#
        另外 $1, $2, $3, $4,          ===> 此时 $# 等于 4,
当执行shift 1 时, 各个位置参数的值向一次向左右1次,此时 $1的值 为原$2的值
当执行shift 2 时, 各个位置参数的值向一次向左右2次,此时 $1的值 为原$3的值。

    完整代码 -------  nicenumber.sh  ---------------------------
    nicenumber()
        .....             # 函数实现部分

    #处理脚本标志参数
    while getopts “d:t:”  opt
    do
        case $opt in                    # $opt  为 具体的标志字符
            d )     DD=”$OPTARG”    ;;        # $OPTARG 为标志指定的参数值
            t )     TD=”$OPTARG”    ;;
            * )     echo “no arg-flag: $opt” >&2    ;    exit 1
esac
done

# 当脚本接收如此多的参数时,$1将不代表脚本最终要处理的大数字,所以做如下操作。
shift $(($OPTIND - 1))   

nicenumber $1
exit 0
----------------------------------------------------------------
扩展:
1.不同国家整数与小数的分隔符不同,使脚本能够处理各种整数与小数各种分隔符情况。在传给脚本参数时需指定标志-d
程序中仅需在 分隔 整数与小数部分略修改为
    integer=$(echo $1 | cut “–d${DD:=”.”” –f1 )
    decimal=$(echo $1 | cut “–d$DD” –f2 )
2.另外,可以在程序执行之前分别初始化DD,TD默认值。
3. 检测传给脚本的大数值中是否含有 非法的整小数分隔符,即存在与用户指定或默认分隔符不同的符号。
   方法:删除其中所有数字,看剩下的内容,若不空且不等于$DD,则非法
    separator=”$(echo $1 | sed ‘s/[[:digit:]]//g’)”
    if [ -n $separator  &&  “$separator” != “$DD” ];then  # 蓝色部分可用 –a 表示
        exit 1
    fi
 
5. 检测 输入整数的合法性,可负数(-1, -2均合法), 可以指定传入整数范围,不在范围内则报错。
参数:1或3个, 当3个时,后两个为范围。
合法性:正负数的判断,范围的判断。
validint()
{
        integer=$1        min=$2        max=$3
    # 判断传参的合法性,以下判断是错误的,因为不管参数是否为空,实际上都传了三个参数。
    if [ $# -eq 0 ];then                   # 改成判断$1的内容是否为空,就可以了
        echo “you couldn’t do nothing>”&2
        return 1
    fi
    #判断是否为负数,第一个字符 是否为 –, 如是,则判断后面的是否为整数。若非负,则判断是否为整数
if [ “$(echo $1 | cut –c1)” = “-” ]; then
        signed=”-”
        integer=”${integer#?}”
    fi
    
    # 如果就是一个符号 -,则也是非法的
    if [ -z “$integer” ]; then
        echo “Invalid input, just a “-” is not allowed”>&2  #注意:>&2 三个字符紧连。
        return 1
    fi
    # 如果非纯数字构成,则非法。
    if [ -n “$(echo $integer | sed ‘s/[[:digit:]]//g’)” ] ; then
        echo “Invalid integer, it includes some char but digit”>&2
        return 1
    fi
    integer=”$signed$integer”
        # 范围判断,注意当 min 和 max 为空时(即未传范围),我设定其为$integer,如此判断就不会出错。
    if [ $integer –lt ${min:=$ingeger} ];then
        echo “$integer is too small, it should greater than $min”>&2
        return 1
    fi
    if [ $integer –gt ${max:=$integer} ];then
        echo “$integer is too large, it should little than $max”>&2
        return 1
    fi
    return 0
}
--------------执行代码------------
#!/bin/bash
validint()
    .....#
if validint “$1”    “$2” “$3”; then
echo “your input is valide”
fi

注:if [ ! -z $min -a "$number" -lt "$min" ] 为AND表达式,但在shall脚本中,当第一个条件为false时,不能保证第二个条件不被测。 而将if条件改写成两层嵌套的if语句后,当第一个为false时,则第二个一个不会被测。
 
6. 检测浮点数的合法性。
参数:1个浮点数 
合法性: 不支持科学表示法,支持带符号  -1.2  -.75均合法。
思路:首先要判断是整数还是浮点数,只是一种可能性的判断,即判断有没有 点
有点的情况:依据“.”劈成两半,前半为合法整数。后半必须为 >=0 的整数。
需调用上一例中的判断整数合法性的validint()函数
无点的情况:基本做整数判断处理

函数: 
validfloat()
{
    fvalue=$1
    # 保证传入参数非空
    if [ -z “$fvalue” ] ; then
        echo “you input nothing”>&2
        return 1
    fi
    # 判断有点否?(清除点以外的字符,看看结果是否为空)
    if [ -n $(echo $fvalue | sed ‘s/[^.]//g’) ] ; then
        integer=”$(echo $fvalue | cut –d. f1 )”
        decimal=”$(echo $fvalue | cut –d. f2 )”
        
        //判断整数部分的合法性,当仅为 – 时,把它看成0,免去判断
        if [ “$integer”  != “-” ] ; then
            if ! validint “$integer” ; then
                echo “part before dot $integer is not valide!”>&2
                return 1
            fi
        fi
        
        //判断小数部分整数的合法性。必须>=0, 当为空时不判断。
        if [ -n “$decimal” ] ; then
            if ! validint “$decimal” 0 ; then
                echo “part after dot $decimal is not valide!”>&2
                return 1
            fi
        fi 
    else
        # 没有点,就当作整数处理
        if  validint “fvalue” ; then
            echo “your input is a integer”>&2
            return 1
        fi
    fi
}

-----------------完整代码 validfloat  ----------------------
#!/bin/bash
. validint            #引用别的文件定义的函数。
validfloat()
    ....        # 实现部分

if validfloat $1 ; then
    echo “$1 is a valid floating-point value”
fi

exit 0
-------------------------------------------------------------

  • 2
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值