初级bash-shell脚本编写和练习

来源:互联网 发布:数据透视表刷新数据 编辑:程序博客网 时间:2024/06/05 05:48
条件测试语法有两种书写模式,一种是[ expression ], 另一种是[[ expression ]],为了在书写条件测试的过程中,不让大家将两种格式相互混淆,那么在这里我只讲一种格式,也就是第一种格式[ ]。因为第一种格式在书写过程中基本不会写错,而第二种格式经常会写错,且第一种格式在很多服务的启动脚本中经常看到,因此应用广。那么为了降低bash编程的门槛,在这里我只讲解第一种,如果对shell编程感兴趣的同学,可以查看《shell脚本编程大全》一书
判断某需求是否满足,需要由测试机制来实现,下面我们就讲讲如何编写测试表达式来实现所需的测试
    条件测试的状态返回值和书写格式
1:执行命令,利用状态返回值来判断
    0:成功
    1-255:失败
2:测试表达式
    test expression
    [ expression ]  常用
    [[ expression ]]
    bash的测试类型
数值测试
字符串测试
文件测试
    数值测试:数值比较
-eq:是否等于 [ $num1 -eq $num2 ]
-ne:是否不等于 [ $num1 -ne $num2 ]
-gt:是否大于 [ $num1 -gt $num2 ]
-ge:是否大于等于 [ $num1 -ge $num2 ]
-lt:是否小于 [ $num1 -lt $num2 ]
-le:是否小于等于 [ $num1 -le $num2 ]
    字符串测试:字符比较
==:是否等于
>:是否大于
<:是否小于
!=:是否不等于
=~:左侧字符串是否能够被右侧的pattern所匹配
-z“string”:判断指定的字符串是否为空 ,空则为真,不空则假
-n“string”:判断指定的字符串是否为不空 ,不空则为真,不空则假
注意:
(1)字符串要加引号
(2)在做字符串的比较的时候,格式如下:
if [ "$VARIABLE" == "$VARIABLE" -a "$VARIABLE" == "cpu" ];then 需要在运算符号两边有空格,并且使用双引号将字符串包裹起来,这样即使是变量也可以替换
    文件测试
存在性测试
    -a file
    -e file
    文件的存在性测试,存在为真,否则为假
文件类型测试
    -b file:是否存在并且为块设备文件
    -c file:是否存在并且为字符设备文件
    -d file:是否存在并且为目录文件
    -f file:是否存在并且为普通文件
    -h/l file:是否存在并且为符号链接文件
    -p file:是否存在并且为管道文件
    -S file:是否存在并且为套接字文件
文件是否有内容
    -s file:是否存在并且有内容
变量是否有为空,为空则为真
    -z ""$VARIABLE"
文件的时间戳测试
    -N file:文件自从上次被读取后是否修改过
从属关系测试
    -O file:当前用户是否为文件的属主
    -G file:当前用户是否属于文件的属组
双目测试
    file1 -ef file2:是否为同一文件系统上的指向同一iNode的硬链接
    file1 -nt file2:file1 是否新于file2
    file1 -ot file2:file1 是否旧于file2
    组合条件测试
逻辑运算
第一种方式
    COMMAND1 && COMMAND2
    COMMAND1 | | COMMAND2
    ! COMMAND
    [-O file]&&[-r file]
第二种方式
    [ expression -a expression ]:与运算
    [ expression -o expression ]:或运算
    ! expression
    例如:[ -O file -a -x file ]
    脚本的状态返回值
1:默认是脚本执行的最后一条命令的返回值
2:自定义状态退出状态码
    exit [n]:n为自己指定的状态码
    注意:shell进程遇到exit时候,会立即终止,整个脚本执行结束

  过程式编程语言的代码执行顺序
顺序执行:逐条运行
选择执行:
    代码存在一个或多个分支,只执行其中一个
    代码有一个分支:条件满足时才会执行
    两个或以上的分支:只会执行其中一个满足条件的分支
循环执行:
    代码片段(循环体)要执行0,1或多个来回
一,选择执行:
单分支的if语句
if 测试条件;then
    如果满足条件就执行这里的代码
fi
    双分支的if语句
if 测试条件;then
    如果满足条件就执行这里的代码
else
    如果不满足条件就执行这里的代码
fi
练习1:通过参数传递一个用户名给脚本,此用户不存在,则添加,密码与用户名相同
#!/bin/bash
if [ $# -lt 1 ];
then
    echo "please send argument"
    exit 1
fi                                    #如果没有传递参数,直接退出
 
 if grep "^$1\>" /etc/passwd &>/dev/null;then  #输入一个参数即用户名与/etc/ passwd进行匹配,
                                                                     若相同则
     echo "user $1 exists
  else                                          #若不相同则创建新用户
     useradd $1
     echo $1 | passwd --stdin $1 &>/dev/null    #将用户名标准输出到密码,/dev/null表示不在屏幕输出
     echo "add user $1"
fi
练习2:通过参数传递一个用户名给脚本,此用户存在,则删除用户以及其家目录和邮件目录
#!/bin/bash
# description
if  [ $# -lt 1 ];then
    echo "please send a argument."
    exit 1
fi
if id -u $1 &> /dev/null;then    #输入一个参数即用户名, id -u可用来检测用户是否存在
    userdel -r $1
    echo "delete user $1"
else
    echo "user $1 doesn't exists"   
fi
练习3:通过命令行参数给定两个数字,输出其中最大的数值
方法1
#!/bin/bash
#如果没有传递参数,直接退出
if [ $# -lt 2 ];
then
    echo "please send two arguments"
    exit 1
fi
if [ $1 -eq $2 ];then
    echo "$1 equals to $2"
    exit 1
fi
if [ $1 -gt $2 ];then
    echo "The big one is $1"
else
    echo "The big one is $2"
fi
方法2
#!/bin/bash
#如果没有传递参数,直接退出
if [ $# -lt 2 ];
then
    echo "please send argument"
    exit 1
fi
declare -i max=$1
if [ $max -lt $2 ];then
    max=$2
fi
    echo "The big one is $max"
练习4:通过命令行参数给定一个用户名,判断其ID号是偶数还是奇数
#!/bin/bash
#如果没有传递参数,直接退出
if [ $# -lt 1 ];
then
    echo "please send argument"
    exit 1
fi
if id -u $1 &> /dev/null;then
    idNum=$(id -u $1)
    let s=$idNum%2        # 判断余数是0还是1,如果是0,那么就是偶数,如果是1,就是奇数
   if [ $s -eq 0 ];then
      echo "$1'IDNum is $idNum and oven"
   else
      echo "$1'IDNum is $idNum and odd"
   fi
else
    echo "user $1 doesn't exits"
fi
练习5:通过命令行参数给定两个两个文件名,如果某文件不存在,则结束脚本执行,如果都存在时返回两个文件的行数之和
#!/bin/bash
#如果没有传递参数,直接退出
if [ $# -lt 2 ];then
    echo "please send two argument"
    exit 1
fi
if [ -e $1 -a -e $2 ];then                       #(-e exist 表示存在, -a and)
   totalLines=$[ $(grep ".*" $1 |wc -l)+$(grep ".*" $2 |wc -l) ]
   echo "The total lines are $totalLines"
else
    echo "The file doesn't exists"
    exit 1
fi
二,read命令:通过键盘输入数据,将键盘输入的值传递给脚本的中定义的变量,从而完成变量赋值操作 。脚本中使用read命令可以使得用户能够与程序进行交互
read [选项] [变量名]
                这里变量名的意义在于将用户输入的值传递给这个变量名,那么在脚本中我们就可以拿到用户输入的值了
选项:
    -p (promp):在用户在键盘输入数据时,指定显示提示符
    -t(timeout):指定超时时间,如果用户在指定的超时时间都没有输入的话,那么就终止脚本的执行
练习:通过脚本创建一个用户,并设置密码,要求:需要用户交互式输入用户名和密码,如果用户名存在,终止脚本,如果不存在就创建,且设置密码
#!/bin/bash
read -p "Enter a user name:" name             #在屏幕上显示提示语句“Enter a user name:”
[ -z "$name" ] && echo "a user name is needed." && exit 1      #-z表示输入的字符串 $name 为空
if id $name &>/dev/null ;then                       #检测用户是否存在
    echo "$name already exists."
    exit 2
else                                           #用户不存在,则创建此用户,并设置密码
    read -p "Enter a passwd for $name,defaults is 'password':" password
    [ -z "$password" ] && password="password"    #将空密码或者输入的不为空的密码传递给密码
    adduser $name
    echo "$password" | password --stdin $name &>/dev/null   #将密码赋给此用户并不在屏幕输出
    echo "Add user $name"
fi
(1)在运行脚本前,我们一般先对脚本的语法进行检查,如果脚本有bug,我们再调试脚本  
语法检查      bash -n 脚本路径
脚本调试      bash -x 脚本路径
(2)过程式编程语言的执行流程       执行顺序  选择顺序  循环顺序
选择执行
(1)&&,|| 
    command1 && command2:如果command1正确,也执行command2;如果command1不正确,不执行command2
    command1 || command2:如果command1正确,不执行command2;如果command1不正确,执行command2
(2)if语句
(3)case语句
if嵌套语句格式
if [ 条件 ];then
    if [ 条件 ];then
        执行这里的代码
    fi
fi

if [ 条件 ];then
    if [ 条件 ];then
        执行这里的代码
    fi
else
    if [ 条件 ];then
        执行这里的代码
    fi
fi

if 多分支语句格式(注意:多个分支只会执行一个,执行首先为真的分支)
if  [ 条件1 ];then
        条件1为真执行这里的代码
elif [ 条件2 ];then
        条件2为真执行这里的代码
elif [ 条件3 ];then
        条件3为真执行这里的代码
.
.
.
elif [ 条件n ];then
        条件n为真执行这里的代码
else
        如果所有的条件都不满足时,执行这里的代码
fi
示例1:通过脚本参数传递一个文件路径给脚本,判断此文件的类型
#!/bin/bash
if [ $# -lt 1 ];then
   echo "A argument is needed."
   exit 1
fi
if ! [ -e $1 ];then
    echo "No such file or directory."
    exit 2
fi
if [ -f $1 ];then
   echo "Common file"
elif [ -d $1 ];then
   echo "Directory file"
elif [ -L $1 ];then
   echo "Symbolic link"
elif [ -b $1 ];then
   echo "block file"
elif [ -c $1 ];then
   echo "character special file"
elif [ -S $1 ];then
   echo "Socket file"
else
   echo "Unknow"
fi
示例2,传递一个参数给脚本,此参数为用户名根据其ID号来判断用户类型:0:管理员 ,1-499:系统用户,500+:为登入用户, 输出用户是那种类型的用户
#!/bin/bash
if [ $# -lt 1 ];then
   echo "A argument is needed."
   exit 1
fi
if id -u $1 &>/dev/null;then
      userid=$(id -u $1)
  if [ $userid -eq 0 ];then
        echo "Administrator"
  elif [ $userid -ge 1 -a $userid -le 499 ];then
        echo "System user"
  elif [ $userid -ge 500 ];then
        echo "Login user"
  fi
else
      echo "No such user."
fi
示例3,1)列出如下菜单给用户disk) show disks infomem)show memory infocpu)show cpu info*)quit
(2)提示用户给出自己的选择,而后显示对应其选择的相应系统信息
#!/bin/bash
cat << EOF
disk) show disks info
mem)show memory info
cpu)show cpu info
*)quit
EOF
read -p "Please input your option:" option
option=$(echo $option | tr [A-Z] [a-z])                  #将输入的大写转换成小写
if [ $option == "disk" ];then
     fdisk -l
elif [ $option == "mem" ];then
     free -m
elif [ $option == "cpu" ];then
     lscpu
elif [ $option == "*" ];then
      exit 1
else
     echo "Wrong option"
fi
循环就是将一段代码重复执行0,1次或多次。
进入条件:条件满足时,需要进入循环 , 退出条件:每个循环都应该有退出条件,有机会退出循环
bash的循环分类: for循环,while循环,until循环
for循环有两种格式 (重点)
        第一种格式:遍历列表 (重点)
        第二种格式:控制变量 (重点)
变量列表
     for 变量 in 列表; do
            循环体
     done
进入条件:只要列表中有元素,即可进入循环 ; 退出循环:列表中的元素遍历完成
示例
#!/bin/bash
for username in user1 user2 user3;do
    if id $username &>/dev/null;then
        echo "$username is already exists."
    else   
        useradd $username
        echo "Add &username success"
     fi
done
列表生成的方式
(1)直接取出
    例如: user1 user2 user3
(2)整数列表
    例如 {1..100}
    例如  `seq 1 2 100`  注意:中间的2表示步长
(3)返回列表的命令
    `ls /var/log/`
(4)glob
    例如: /var/log/*
(5)变量引用,如:@* ,
    示例1:求100内所有正整数之和
#!/bin/bash
# 求100内所有正整数之和
# 申明sum为正整数
declare -i sum=0
for i in {1..100}; do
    sum=$[ $sum+$i ]
done
echo "$sum" 
    示例2:列出/var/log/目录下所有文件的类型
#!/bin/bash
# 列出/var/log/目录下所有文件的类型
for option in /var/log/*; do
    if [ -f $option ];then
        echo "$option is Common file"
    elif [ -d $option ];then
        echo "$option is Directory"
    elif [ -L $option ];then
        echo "$option is Symbolic link"
    elif [ -b $option ];then
        echo "$option is block special file"
    elif [  -c $option ];then
        echo "$option is character special file"
    elif [  -S $option ];then
        echo "$option is Socket file"
    else
        echo "Unknow"
    fi
done
    练习1:分别求100以内所有偶数之和,奇数之和
#!/bin/bash
# 1:分别求100以内所有偶数之和,奇数之和
declare -i oven=0
declare -i odd=0
for i in {1..100}; do
    count=$[ $i % 2 ]
    if [[ $count == 0 ]]; then
        oven=$[ $oven + $i ]
    else
        odd=$[ $odd + $i ]
    fi
done
echo "oven is $oven"
echo "odd is $odd"    
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 苹果6s屏幕摔碎了怎么办 苹果手机掉在水里了怎么办 乐视手机掉水里没法触屏了怎么办 乐视电视有声音但是黑屏怎么办 苹果手机微信语音有回音怎么办 苹果4s死机了没反应了怎么办 苹果手表的显示平坏了怎么办 苹果5s屏幕翘起来了怎么办 苹果手机圆点卡住屏幕不能动怎么办 苹果5s卡屏怎么也不动应该怎么办 苹果5s手机触摸屏太灵敏怎么办 苹果5s手机关机滑动失灵怎么办 苹果5s关机开机后没信号怎么办 苹果手机5s被弄关机了怎么办 华为荣耀5c换屏后触摸失灵怎么办 三星笔记本鼠标触摸板没反应怎么办 有米6x触摸屏不好使怎么办? 小米5s屏幕触摸没反应怎么办 苹果5s主屏幕设置没反应怎么办 华为畅享5s接听不灵怎么办 红米3s忘记锁屏密码怎么办 华为畅享5s手机打不开网络怎么办 苹果手机突然关机开不了机怎么办 苹果手机掉地上开不了机怎么办 oppo手机突然黑屏开不了机怎么办 苹果6s为什么开不了机怎么办 苹果手机还原出厂设置白苹果怎么办 捡到苹果6s手机怎么办才能自己用 苹果6s玩游戏卡住了怎么办 苹果6s进水换屏后指纹失灵怎么办 苹果手机6s声音按键失灵怎么办 苹果手机触屏失灵怎么办5s 苹果六摔了一下屏幕失灵怎么办 荣耀5c进水屏幕触摸屏失灵怎么办 生活玩家打不了风云蝙蝠岛怎么办啊 企鹅号在注册的时候选错领域怎么办 博士超期学信网的信息被删除怎么办 电脑账号删除后电脑开不了怎么办 lol不小心融错了皮肤怎么办 农村医保交费了没有录入系统怎么办 电动三轮车在泗阳被交警扣了怎么办