avatar

目录
几个Linux的Shell编程例子

前言

Shell 是一个用 C 语言编写的程序,这个应用程序提供了一个界面,用户通过这个界面访问操作系统内核的服务。它是用户使用 Linux 的桥梁。Shell 既是一种命令语言,又是一种程序设计语言。

Shell 脚本,是一种为 shell 编写的脚本程序。业界所说的 shell 通常都是指 shell 脚本,但要注意的是,shell和shell script是两个不同的概念。由于习惯的原因,人们经常说的“shell编程”都是指 shell 脚本编程,而不是指开发 shell 自身。

Shell 编程跟Python、Php 等语言的编程一样,只要有一个能编写代码的文本编辑器和一个能解释执行的脚本解释器就可以开始编程。

1 找出100以内的素数

只能被1和它本身整除的数称为素数。

代码:

#!/bin/bash  
judge() #定义函数 
{  
    i=2;  
    flag=1;  
    while [ $i -lt $num ]  #从2开始循环检测小于num的所有正数,看是否能整除num
    do  
    let "m=num%i"  #计算表达式
    if [ $m -eq 0 ]  
    then  
        flag=0;  #标记出不是素数
        break;  
    fi  #闭合if
    let "i=i+1"  
    done  
    if [ $flag -eq 1 ]  
    then   
    printf "%d " $num  
    fi   
}  
num=2  
while [ $num -lt 100 ]  #在100以内循环
do  
    judge   #调用函数
    let "num=num+1"  
done 

运行结果:

2 判断回文数

如果一个数的数字按相反的顺序排列后,得到数和原来的数一样,这个数就被叫做回文数。例入121,12321等等,而且个位数一定是回文数。

代码:

#!/bin/bash   
judge() #定义函数  
{  
    x=$1  #传参
    sum=0  
    origin=$x       #引用前面定义过的变量要加$  
    while [ $x -ne 0 ]  #中括号里面的字符不能紧贴中括号  
    do  
    let "num=x%10"  
    let "sum=sum*10+num"  
    let "x=x/10"  
    done  
    if [ $sum -eq $origin ]  
    then  
    echo "Yes"  
    else  
    echo "No"  
    fi  
}  

#主程序入口  
#判断传参的合法性  
if [ $1 -lt 0 ]  #判断数字是否为负数
then  
    echo "the number is minus" >&2  
    exit 1  
fi  

judge $1   #输入1个参数,调用函数  

运行结果:

3 判断整数是否规范

判断给出的整数是否符合规范,同时还可以如果同时给出三个参数,还可以判断第一个整数是否在第二和第三个整数之间。

代码:

#!/bin/bash  
judge()  #定义函数
{  
    signed=""     #初始化  
    integer=$1  min=$2  max=$3  
    #判断是否为负数,第一个字符是否为-。如是,则判断后面的是否为整数;若非负,则判断是否为整数。  
    if [ "$(echo $1 | cut -c1)" = "-" ]   
    then  
        signed="-"  
        integer="${integer#?}" #${variable#pattern}把variable中的内容去掉左边最短的匹配模式,?表示仅与一个任意字符匹配  
    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:=$integer} ]   #-lt表示小于
    then   #":="代表若min值为空则赋值成默认的integer,若min已被赋值则为不再以integer赋值
            echo "$integer is too small,it should greater than $min" >&2  
            return 1  
      fi  
      if [ $integer -gt ${max:=$integer} ]    #-lt表示大于, ":="的用法同上
      then  
           echo "$integer is too large,it should little than $max" >&2  
           return 1  
      fi  
    return 0  
}  

#主程序
#判断传参的合法性  
if [ $1 -eq 0 ]  
then  
    echo "you could not do nothing" >&2  
    exit 1  
fi  

if judge "$1" "$2" "$3"    #三个参数,$2和$3表范围可以缺省  
then  
    echo "your input integer is valid"  
fi  

运行结果:

4 判断日期

给出一个日期,能够判断当年是否为闰年和当月天数,并给出明天的日期。

代码:

#!/bin/sh  
judge_leap() #判断是否闰年  
{  #expr是一个手工命令行计数器,可以求表达式变量的值
    Y=`expr substr $1 1 4`  
    r1=`expr $Y \% 4`     #if((year%4==0&&year%100!=0)||year%400==0)  
    r2=`expr $Y \% 100`   #(1)普通年能被4整除且不能被100整除的为闰年,(2)世纪年能被400整除的是闰年。  
    r3=`expr $Y \% 400`  

    if [ "$r1" -eq 0 -a "$r2" -ne 0 -o "$r3" -eq 0 ];then  #年月日同时不为0
        FRUN="true"  
    else  
        FRUN="false"  
    fi  
    echo $FRUN  
}  

get_mon_days() # 获取当月天数  
{  
    Y=`expr substr $1 1 4`  #从$1中取出标号1-4的字符,得年份
    M=`expr substr $1 5 2`  #从$1中取出标号5-2的字符,得月份

    case "$M" in  #case语句来处理月份
         01|03|05|07|08|10|12) days=31;;  
         04|06|09|11) days=30;;  
         02)  
        _tmpStr=`check_leap "$Y"`  #判断是否闰年,调用函数  
        if [ "$_tmpStr" = "true" ] ; then  
            days=29  
        else  
            days=28  
        fi  
        ;;  
         *)  
        days=0  
        ;;  
    esac  
    echo $days  
}  

check_date() #检查日期格式(例:20141022)  
{  
    [ $# -ne 1 ] && return 1     #检查是否传入一个参数  

    _lenStr=`expr length "$1"`  #检查字符串长度  
    [ "$_lenStr" -ne 8 ] && return 1  

    _tmpStr=`echo "$1" | grep "^[^0][0-9]*$"`    #检查是否输入的是非0开头的数字  
    [ -z "$_tmpStr" ] && return 1  

    Y=`expr substr $1 1 4`  
    M=`expr substr $1 5 2`  
    D=`expr substr $1 7 2`  
    [ "$M" -lt 1 -o "$M" -gt 12 ] && return 1    #检查月份  
    days=`get_mon_days "$Y$M"`    #取当月天数  
    [ "$D" -lt 1 -o "$D" -gt "$days" ] && return 1    #检查日  

    return 0  
}  

get_next_date() #返回明天日期  
{  
    Y=`expr substr $1 1 4`  
    M=`expr substr $1 5 2`  
    D=`expr substr $1 7 2`  

    dad=`get_mon_days "$Y$M"`  #当月天数  

    if [ "$D" = "$dad" ];then          #月底的情况  
        if [ "$M$D" = "1231" ];then              #年底的情况  
            YY=`expr $Y + 1`  
            next_date="${YY}0101"  
        else  
            MM=`expr $M + 1`  
            MM=`printf "%02d" $MM`  
            next_date="$Y${MM}01"  
        fi  
    else  
        #通常情况  
        DD=`expr $D + 1`  
        DD=`printf "%02d" $DD`  
        next_date="$Y$M$DD"  
    fi  

    echo $next_date  
}  

#主程序  

#处理MM/DD/YYYY 和MM-DD-YYYY 的形式
#set 的--命令可以将其后的参数赋予位置参数$1、$2和$3 
set -- $(echo $1 | sed 's/[\/\-]/ /g')  


#检查日期格式  
_dateStr="$1$2$3"  
check_date $_dateStr  
if [ $? -eq 1 ];then  #提示出错
    echo "输入日期[$1]格式错误!示例:(`date +%Y%m%d`)"  
    exit 1  
fi  

cat <

运行结果:

参考:

[1] Shell教程. https://www.runoob.com/linux/linux-shell.html.

[2] Wicked Cool Shell Scripts, 2nd Edition.

文章作者: crownZ
文章链接: https://crownz-sec.github.io/2020/04/23/linux_shell/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 crownZ's Blog

评论