20 shell脚本编程1

20 shell脚本编程1

一、杂项知识整理

1、脚本文件格式:

    #!/bin/bash

    (注释信息:)

    #description:say hello

    #vesion:1.4.

    #author:Jerry

    #date:20160718

    (代码注释:)

    (缩进 适度添加空白行)

shell脚本的用途有:

    自动化常用命令

    执行系统管理和故障排除

    创建简单的应用程序

    处理文本或文件

2、运行脚本的两种方式:

    bash file.sh

    chmod +x file.sh    . file.sh

脚本调试:

    bash -n 检查脚本中的语法错误

    bash -x 调试执行,显示执行过程

3、变量:

    变量:命令的内存空间

        数据存储方式:

            字符:

            数值:整型,浮点型

    作用:

        数据存储格式

        参与的运算

        表示的数据范围

    类型:

        字符型

        数值型:整型,浮点型

    命名法则:

        不能使用程序中的保留字如if for等

        只能使用数字、字母及下划线,且不能以数字开头

        见名知义

        统一命名规则:驼峰命名法

4、bash中的算数运算:help let

    + – * / %取余 **乘方

    实现算术运算:let var=算术表达式

        var=$[expr]

            赋值公式中等号两边不能有空格,有空格的是比较运算。

        var=$((expr))

        var=$(expr arg1 arg2 arg3…)

        declare -i var=数值

        echo ‘算数表达式’ | bc

    乘法符号有些场景中需要转义,expr 3 \* 4,expr没有乘方运算

    使用expr的时候需要每个字符串都加空格,否则识别为一个字符串:expr 1 + 3 

使用bc命令可以使用计算器,重定向给计算器也可以进行计算,bc计算器可以直接使用正常算法格式如23+25,2^4等。

    其中乘方使用bc如上,使用其他方式的时候是**,如

[root@centos68 tmp]# let a=2**4
[root@centos68 tmp]# echo $a
16

    bash有内建的随机数生成器:$RANDOM(1-32767)

    echo $[RANDOM%50] :0-49之间的随机数

    echo $[RANDOM%50+1]:取余之后的结果加1,表示1-50之间的随机数。

5、增强型复制:

    += -= *= /= %= 自身进行运算之后再赋值给自己

    自增自减:let var+=1

                let var++

            a++ 和 ++a是有区别的,运算顺序不一样

                let var-=1

                let var–

6、短路运算:

    短路与:第一个为0,结果必定为0

        第一个为1,第二个必须要参与运算

    短路或:第一个为1,结果必定为1

        第一个为0,第二个必须要参与运算

    异或:^ 异或的两个值,相同为假,不同为真

7、两种聚集命令的方法:

    复合式:date;who | wc -l 命令会一个接一个地运行

    子shell:(date;who | wc -l) >>/tmp/trace 所有的输出都被发送给单个stdout和stderr。

8、测试命令:

    test EXPRESSION

        格式相同,就是去掉了括号

    [ EXPRESSION ]

    [[ EXPRESSION ]] EXPRESSION前后必须有空白字符

如test a = b   [ a = b ] [[ a = b ]]

数值测试:

    -gt 是否大于

    -ge 是否大于等于

    -lt 是否小于

    -le 是否小于等于

    -eq 是否等于

    -ne 是否不等于

字符串测试:

    == 是否等于

    > 是否大于 acsii码

    < 是否小于

    != 是否不等于

    =~ 左侧字符串是否能够被右侧的PATTERN所匹配。注意,此表达式一般用于[[]]中

    -z “string” 字符串是否为空,空为真,不空为假

    -n “string” 字符串是否为不空,不空为真,空为假

    注意:用于字符串比较时的用到的操作数都应该使用引号

文件测试:

    -a FILE 文件存在性测试,存在为假,否则为真

    -e FILE 文件存在性测试,存在为真,否则为假

    -b FILE 是否存在且为块设备文件

    -c FILE 是否存在且为字符设备文件

    -d FILE 是否存在且为目录文件

    -f FILE 是否存在且为普通文件

    -h FILE 或-L FILE 存在且为符号链接文件 

    -p FILE 是否存在且为管道文件

    -S(大写) FILE 是否存在且为套接字文件

    -r FILE 是否存在且可读

    -w FILE 是否存在且可写

    -x FILE 是否存在且可执行

    检测的是实际权限,与显示的权限位不一定相同,例如root

    -g FILE 是否存在且拥有sgid权限

    -u FILE 是否存在且拥有suid权限

    -k FILE 是否存在且拥有sticky权限

    -s(小写) 是否有内容,有内容为真

    -t fd:fd表示文件描述符是否已经打开且与某终端相关

    -N FILE 文件自上一次被读取之后是否被修改过

    -O FILE 当前有效用户是否为文件属主

    -G FILE 当前有效用户是否为文件属组

双目测试:FILE1 -ef FILE2:两个文件是否指向同一个设备上的相同inode

                FILE1 -nt FILE2 :FILE1是否新与FILE2

            FILE1 -ot FILE2 : FILE1是否旧于FILE2

8、组合测试条件:

    第一种方式:

    COMMAND1 && COMMADN2 并且

    COMMAND1 || COMMAND2 或者

    !COMMAND 非

        如:[ -e FILE ] && [ -r FILE ]

    第二种方式:

    EXPR1 -a EXPR2 并且

    EXPR1 -o EXPR2 或者

    !EXPR 非

        必须使用测试命令进行

9、查看所有内部命令:man bash  或  enable

   同名文件用mv和cp两个命令覆盖的区别:mv是改变了其索引,inode号没有变,也就是指元数据没变化。cp覆盖是新建了文件,数据也重新迁移,inode号也就改变了。

10、Linux中运行命令或者脚本,按照PATH变量给定的路径。windows先搜索当前目录再按照path变量寻找。

11、netstat -nt 查看活动网络连接;touch /etc/nologin,可以禁止普通用户登录!另外可以usermod -L和-U 以及passwd -l和-u进行禁止。

12、

二、练习及课后作业

1、变量类型及区别:

    本地变量:生效范围是当前shell进程;对低昂前shell之外的其他shell进程,包括当前shell的子shell进程均无效。

        赋值name=‘value’ 可以使用引用value,可以是直接字串name=“root”;变量引用:name=“$USER”;命令引用:name=`command` name=$(command)

        变量引用:${name}  $name

        "" 弱引用,其中的变量引用会被替换为变量值

        ‘’强引用,其中的变量引用不会被替换为变量值

        显示已定义的所有变量:set

        删除变量:unset name(在脚本执行结束后一定要删除使用的变量以清空内存空间)

    环境变量:生效范围为当前shell进程及子进程

        环境变量:变量声明、赋值:export name=VALUE

            declare -x name=VALUE

        变量引用:$name $(name)

        显示所有环境变量:export env  printenv

        删除:unset name

    局部变量:生效范围为当前shell进程中某代码片段(通常指函数)

    位置变量:$1,$2…来表示,用于让脚本代码中调用通过命令行传递给它的参数

        只读变量:readonly name  

                    declare -r name

        也可以同时设置为环境变量

        在脚本代码中调用通过命令行传递给脚本的参数

            $1 $2…${10}…对应第1 第2…第10个参数,shift [n] 换位置

    特殊变量:$?上一条命令的执行返回值,错误为0,正确为1-254

         $0 脚本文件路径本身

         $@ 传递给脚本的所有参数,每个参数为独立字符串

         $# 显示使用了哪几个参数

         $* 传递给脚本的所有参数,全部参数合为一个字符串

                $@和$*只在被双引号包起来时候才会有差异

2、编写脚本/root/bin/systeminfo.sh,显示当前主机系统信息,包括主机名,IPv4地址,操作系统版本,内核版本,CPU型号,内存大小,硬盘大小。

  1 #!/bin/bash
  2 #test 1 
  3 #info
  4 
  5 echo "The hostname is : $(hostname)"
  6 echo "The IP is: $(ifconfig | head -2 | tail -1 | tr -s " "| cut -d" " -f3)"
  7 echo "The OS mode: $(cat /etc/system-release)"
  8 echo "The kernel mode: $(uname -r)"
  9 echo "The memory infomation: $(top | head -4 | tail -1 | cut -d: -f2)"
 10 echo "The disk infomation : $(fdisk -l | grep "Disk /dev/sda:*" | cut -d, -f1 | cut -d: -f2)"

3、编写脚本/root/bin/backup.sh,可实现每日将/etc/目录备份到/root/etcYYYY-mm-dd中

  1 #!/bin/bash
  2 #test2
  3 #bak
  4 
  5 cp -rf /etc  /root/etc$(date +%F)
  6 #

4、编写脚本/root/bin/disk.sh,显示当前硬盘分区中空间利用率最大的值

#!/bin/bash
echo "The max using rate is:`df |grep "/dev/sd"| cut -c 44-46 | sort -nr | head -1`%" 
[root@centos68 shelltest]# bash disk.sh 
The max using rate is: 41%

5、编写脚本/root/bin/links.sh,显示正连接本主机的每个远程主机的IPv4地址和连接数,并按连接数从大到小排序。

#!/bin/bash
#test 4
#Des
echo "the links number is:"
netstat -nt |tr -s ' '  |cut -d ' ' -f5 |cut -d: -f1 |grep [0-9]|sort |uniq -c|sort -nr

6、写一个脚本/root/bin/sumid.sh,计算/etc/passwd文件中的第10个用户和第20用户的ID和

#!/bin/bash
#test 5
NUM1=`cat /etc/passwd | head -10 | tail -1 | cut -d: -f3`
NUM2=`cat /etc/passwd | head -20 | tail -1 | cut -d: -f3`
SUM=$[$NUM1+$NUM2]
echo "The id sum is: $SUM"
[root@centos68 shelltest]# bash -x sumid.sh
++ tail -1
++ cut -d: -f3
++ cat /etc/passwd
++ head -10
+ NUM1=10
++ cut -d: -f3
++ tail -1
++ cat /etc/passwd
++ head -20
+ NUM2=499
+ SUM=509
+ echo 'The id sum is: 509'
The id sum is: 509

7、写一个脚本/root/bin/sumspace.sh,传递两个文件路径作为参数给脚本,计算这两个文件中所有空白行之和

#!/bin/bash
#version
#Des
#test 2
NUM1=`cat $1 | grep  "^$" | wc -l`
NUM2=`cat $2 | grep  "^$" | wc -l`
SUM=$[$NUM1+$NUM2]
echo "space lines: $SUM"
unset NUM1 NUM2 SUM

8、写一个脚本/root/bin/sumfile.sh,统计/etc, /var, /usr目录中共有多少个一级子目录和文件

#!/bin/bash
#test8
#Des:acount
NUM1=`ls -a /etc/ | wc -l`
NUM2=`ls -a /var/ | wc -l`
NUM3=`ls -a /usr/ | wc -l`
SUM=$[$NUM1+$NUM2+$NUM3]
echo "The acount of all files :$SUM

原创文章,作者:SilencePavilion,如若转载,请注明出处:http://www.178linux.com/31941

评论列表(1条)

  • 马哥教育
    马哥教育 2016-08-12 16:04

    文章整体结构清晰,层次分明,通过练习对shelll脚本基础有了深刻的认识,希望能保持下去。