shell命令行解析器2.0

1 shell中的控制语句

1.1 if/elif/else语句使用

        需要注意的是if语句有很多空格,漏掉就会报错。

一、if语句
用法1:
if [ 判断条件 ]
then
    语句块;
fi

用法2:
if [ 判断条件 ]
then
    语句块1;
elif [ 判断条件 ]
then
    语句块2;
else
    语句块n;
fi

用法3:
if ((判断条件,可以按C的格式写))
then
    语句块;
fi

1.2 case/in语句

  1. 匹配项可以是统配符号

    • *通配符号:匹配任意多个字符

    • [a-z]通配符:匹配a-z中的任意一个字符

      [0-9]:匹配0-9中的任意一个字符

      [^345]: 匹配一个除345之外的任意一个字符

    • ?通配符:表示匹配任意的一个字符

    • 匹配项可以多个:"YES"|"yes"|"y"|"Y")

case $变量 in
     匹配项1)
          语句块1
          ;;
     匹配项2)
          语句块2
          ;;
     *)
          语句块n;
          ;;
esac 

案例代码:

#!/bin/bash

read -p "input year month > " year month

if ((year < 0 || month < 1 || month > 12))
then
    echo "输入的年或月不正确"
    exit
fi

case $month in
    1|3|5|7|8|10|12)
        echo "$year-$month有:31天"
        ;;
    4|6|9|11)
        echo "$year-$month有:30天"
        ;;
    2)
        if ((((year%4==0)&&(year%100!=0))||((year%400)==0)))
        then
            echo "$year-$month有:29天"
        else
            echo "$year-$month有:28天"
        fi
        ;;
    *)
        echo "输入错误,请重试"
        ;;
esac

1.3 while循环语句

#用法1
while [ 循环条件 ]
do
 循环体 #如果循环条件为真循环体执行
done

#用法2
while true  
do
 循环体  #死循环
done

#用法3
while ((循环条件))
do
 循环体 #如果循环条件为真循环体执行
done

1.4 for循环

#用法1 (类似c语言的写法)
for ((i=0;i<10;i++))
do
 循环体
done

#用法2
for 变量 in 单词列表(以空格分隔的字符串)
do
 循环体
done

#用法3 
for 变量   #在执行脚本的时候可以传参,这个参数会作为for循环的单词列表
do
 循环体
done

1.5 select/in循环

select 变量 in 单词列表
do
 循环体
done

1.5.1 select/in案例

#!/bin/bash
PS3="input > "  #系统的环境变量,默认值是#?,可以修改成任意格式
select var in abc 123 def
do
    echo "$var"  #用户选择哪个单词,echo就输出哪个参数
done

执行效果:

linux@ubuntu:~/work/day4$ bash 09select.sh 
1) abc
2) 123
3) def
input > 1
abc
input > 2
123
input > 3
def
input >   #这里可以输入ctrl+d或ctrl+c结束选择
    #ctrl+d结束select/in语句
    #ctrl+c结束整个程序

1.6 shell中的break和continue

shell中的break是用于退出循环的,break的语法格式

break n 退出n层循环

#!/bin/bash

while true
do
    i=0
    echo "这是外循环"
    sleep 1
    while true
    do
        ((i++))
        echo "这是内循环"
        sleep 1
        if ((i==5))
        then
            break 2 #退出就近的两层循环
        fi
    done
done

continue结束本次循环进而执行下一次循环,continue的语法格式

continue n

#!/bin/bash

i=1
sum=0
while [ $i -le 100 ]
do
    echo "这是外循环,i=$i"
    while [ $i -le 100 ]
    do
        if ((i%2!=0))
        then
            ((i++))
            continue 2 #结束本次循环,进而执行最外层的下一次循环
        fi
        ((sum+=i++))
    done

done

echo $sum

2 不同对象的判断方法

(1)字符串对象(一定要注意在进行字符串的判断的时候都需要加上"")
    -z 判断字符串是否为空            
    -n 判断字符串是否为非空        
    =或== 都是用来判读字符串是否相等  
    != 不等于           
    \> 大于 (防止误认为重定向)  
    \< 小于                
    练习1:输入两个字符串,判断大小

(2)数字对象
    -eq : 等于     
    -ne : 不等于    
    -gt : 大于      
    -lt : 小于  
    -ge : 大于等于  
    -le : 小于等于   
    练习2:请输入一个学生的成绩,判断学生等级 
    练习3:输入年份,判断平闰年

(3)文件属性
    -b filename 判断文件是否存在,是否是块设备    
    -c filename 判断文件是否存在,是否是字符设备  
    -d filename 判断文件是否存在,是否是目录      
    -f filename 判断文件是否存在,是否是普通文件   
    -p filename 判断文件是否存在,是否是管道文件   
    -L filename 判断文件是否存在,是否是链接文件 (经测试链接文件也是普通文件)
    -S filename 判断文件是否存在,是否是套接字文件 
    -e filename 判断文件是否存在
    -s filename 判断文件是否存在,判断文件是否为空
    练习4:输入文件名,输出文件的类型

(4)文件权限
    -r filename 判断文件是否存在,是否有可读权限 
    -w filename 判断文件是否存在,是否有可写权限  
    -x filename 判断文件是否存在,是否有可执行权限
    练习5:输入文件名判断文件是否有可写权限,如果没有给它加上
    可写权限,然后向文件最后追加一句话

(5)文件比较
    -nt 文件是否更新 
    -ot 文件是否更旧 
    -ef 文件的inode是否一致 

(6)逻辑运算
    -a 与   
    -o 或  
    ! 非

3 shell中函数的介绍

  1. function修饰函数,可以省略,但习惯上不省略

  2. 函数名的命令规则和c语言函数的命名规则一样

  3. shell中所有的函数都没有参数列表,但是可以传参

    在函数内可以通过位置变量获取给函数传递的参数

    $0:脚本名

    $1:函数的第1个参数

    $2:函数的第2个参数

    ${n}:函数的第n个参数

    $#:函数参数的个数

    $@$*:给函数传递的所有的参数

  4. 函数体都需要写在{}内

  5. 在shell中可以通过return返回[0-255]的结果,如果要返回其他结果通过echo完成

  6. shell中的函数不会自动执行,只有调用函数的时候函数才会执行。

    函数名 参数列表

function 函数名()
{
 #函数体
 return 结果;
}

3.1 shell函数的案例

1.通过return返回结果的实例
#!/bin/bash
#封装了求和的函数
function add()
{
    #sum变量默认是全局变量,如果想要让sum变为局部变量需要local修饰
    local sum=0
    ((sum=$1+$2))
    return $sum #return返回的结果只能是[0-255]之间的数
}
#调用函数
add 11 22  
#echo $sum
echo $?  #获取上一步函数执行的结果
2.通过echo加命令置换可以返回结果的实例
#!/bin/bash

function add()
{
    local sum=0
    ((sum=$1+$2))
    echo $sum
}

ret=`add 255 255` #将echo命令执行的结果命令置换给了ret变量,这里就没有0-255的限制了
echo $ret

3.2 shell函数的练习

1.编写一个加法器的函数,在执行脚本的时候可以传递参数,用户可以输入任意多个参数,让它们求和后输出结果
#!/bin/bash
function add()
{
    local sum=0
    for var in $@  #接收传递给函数的所有参数
    do
        ((sum+=var))
    done

    echo $sum
}
ret=`add $@` #接收终端传递过来的所有参数,然后把它们传递给函数
echo $ret
2.封装打印二进制的函数
#!/bin/bash

function print_bin()
{
    local result="0b"
    local flags=0
    #可以通过$1获取num的结果
    for ((i=0;i<32;i++))
    do
        if ((($1<<i)&0x80000000))
        then
            result="${result}1"
            flags=1
        else
            if [ $flags -eq 1 ]
            then
                result="${result}0"
            fi
        fi
    done
    echo $result
}

read -p "input num > " num
result=`print_bin $num`
echo $result
3.输入用户名判断用户是否存在,如果存在就将用户的uid和gid输出
#!/bin/bash
function check_user()
{
    local line=0
    line=`grep "^$1" -nw /etc/passwd|cut -d ":" -f 1`
    echo $line
}

function get_user_info()
{
    local info=0
    info=`head -$1 /etc/passwd | tail -1 | cut -d : -f 3,4`
    echo $info
}

read -p "input username > " usrname

if [ -n "$usrname" ]
then
    line=`check_user $usrname`
    if [ -n "$line" ]
    then
        echo "查询的用户${usrname}存在"
        info=`get_user_info $line`
        echo "查询到用户的UID:GID是=> $info"
    else
        echo "查询的用户不存在,请重试"
    fi
else
    echo "输入错误,请重试"
    exit
fi

4 练习代码

1.使用if判断字符串是否相等
#!/bin/bash
read -p "input str1 > " str1
read -p "input str2 > " str2

if [ -z "$str1" -o -z "$str2" ]
then
    echo "input empty error,try again"
    exit
fi

if [ "$str1" = "$str2" ]
then
    echo "str1 = str2"
elif [ "$str1" \> "$str2" ]
then
    echo "str1 > str2"
else
    echo "str1 < str2"
fi
2.请输入一个学生的成绩,判断它是哪个等级,将学生等级输出到终端
#!/bin/bash

read -p "input score > " score

if [ -z "$score" ]
then
    echo "学生成绩不能是空,请重试"
    exit
else
    if [ $score -lt 0 -o $score -gt 100 ]
    then
        echo "学生成绩的范围[0-100],输入错误,请重试"
        exit
    fi
fi

if [ $score -ge 90 ]
then
    echo "A"
elif [ $score -ge 80 ]
then
    echo "B"
elif [ $score -ge 70 ]
then
    echo "C"
elif [ $score -ge 60 ]
then
    echo "D"
else
    echo "E"
fi
3.输入年份,判断平闰年

判断方法:如果能被4整除不能被100整除或者能被400整除的年是闰年
#!/bin/bash

read -p "input year > " year

if [ -z "$year" ]
then
    echo "输入的年份不能为空"
    exit
fi

#if [ $((year%4)) -eq 0 -a $((year%100)) -ne 0 -o $((year%400)) -eq 0 ]
if (( ((year%4==0)&&(year%100!=0))||(year%400==0) ))
then
    echo "闰年,366天"
else
    echo "平年,365天"
fi
4.输入文件名,输出文件的类型
#!/bin/bash

read -p "input file > " file

if [ -z "$file" ]
then
    echo "输入的文件名为空,请重试"
    exit
fi

if [ -f $file ]
then
    echo "$file是普通文件"
fi
5.输入文件名判断文件是否是普通文件,如果是普通文件判断是否有可写权限,如果没有给它加上

可写权限,然后向文件最后追加"hello world"
#!/bin/bash

read -p "input filename > " file

if [ -z "$file" ]
then
    echo "输入为空,请重试"
    exit
fi

if [ -f $file ]
then
    if [ ! -w $file ]
    then
        chmod u+w $file 
    fi
    echo  "hello world" >> $file
else
    echo "$file不存在或不是普通文件,请重试"
fi
6.判断文件时间戳新旧
#!/bin/bash

read -p "input file1 > " file1
read -p "input file2 > " file2

if [ $file1 -nt $file2 ]
then
    echo "$file1新于$file2"
else
    echo "$file1旧于$file2"
fi
7.判断用户家目录下是否存在file-dir和dir-dir目录,如果不存在就创建,如果存在就清空

向脚本输入任意一个路径,将这个路径下的文件拷贝到file-dir下将目录拷贝到dir-dir下

输出拷贝的文件的个数和目录的个数
#!/bin/bash
arr=("/home/linux/file-dir" "/home/linux/dir-dir")

n=${#arr[*]}
i=0
while [ $i -lt $n ]
do
    if [ -d ${arr[$i]} ]
    then
        echo "目录存在,清除了目录下的所有文件"
        rm -rf ${arr[$i]}
        mkdir  ${arr[$i]}
    else
        if [ -e ${arr[$i]} ]
        then
            echo "存在了其他类型的文件,已移除${arr[$i]}"
            rm -rf ${arr[$i]}
        fi
        echo "新建了${arr[$i]}目录"
        mkdir  ${arr[$i]}
    fi
    ((i++))
done 


read -p "input path> " path
if [ -d $path ]
then
    file_arr=(`ls $path`)
    x=${#file_arr[*]}
    j=0
    f=0
    d=0
    while [ $j -lt $x ]
    do
        if [ -f $path/${file_arr[$j]} ]
        then
            cp  $path/${file_arr[$j]}  ${arr[0]}
            ((f++))
        elif [ -d  $path/${file_arr[$j]} ]
        then
            cp  $path/${file_arr[$j]}  ${arr[1]} -r
            ((d++))
        fi
        ((j++))
    done
else
    echo "输入的路径错误,请重试"
    exit
fi

echo "拷贝的文件的个数:$f"
echo "拷贝的目录的个数:$d"
8.使用shell脚本编写一个实时时钟代码
#!/bin/bash
year=2024
month=2
day=29
hour=23
min=59
sec=55

clear

while true
do
    ((sec++))
    if [ $sec -ge 60 ]
    then
        ((sec=0))
        ((min++))
        if [ $min -ge 60 ]
        then
            ((min=0))
            ((hour++))
            if [ $hour -ge 24 ]
            then
                ((hour=0))
                ((day++))
                case $month in
                    1|3|5|7|8|10|12)
                    if [ $day -gt 31 ]
                    then
                        ((day=1))
                        ((month++))
                    fi    
                    ;;
                    4|6|9|11)
                    if [ $day -gt 30 ]
                    then
                        ((day=1))
                        ((month++))
                    fi   
                    ;;
                    2)
                    if (((year%4==0 && year%100!=0)||(year%400==0)))
                    then
                        if [ $day -gt 29 ]
                        then
                            ((day=1))
                            ((month++))
                        fi  
                    else
                        if [ $day -gt 28 ]
                        then
                            ((day=1))
                            ((month++))
                        fi  
                    fi
                    ;;
                    *)
                        echo "month error,try again"
                        exit
                    ;;
                esac
                if [ $month -gt 12 ]
                then
                    ((month=1))
                    ((year++))
                fi
            fi
        fi
    fi
    printf "%d-%02d-%02d %02d:%02d:%02d\r" $year $month $day $hour $min $sec
    sleep 1
done

  • 10
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值