linux—shell脚本编程

1、 编程基础
  1> 程序:指令+数据
    程序的执行方式:运行二进制指令

  2> 程序编程风格:
    过程式:以指令为中心,数据服务于指令
    对象式:以数据为中心,指令服务数据

  3> 编程语言:
    低级:汇编
    高级:
      编译:高级语言→编译器→目标代码(java,C)  #管理员要编译
      解释:高级语言→解释器→机器代码(shell,perl,python)  #底层自动翻译

  4> shell 程序:提供了编程能力,解释执行

  5> 编程基本概念
    编程逻辑处理方式:顺序执行、循环执行、选择执行
    shell 编程:过程式、解释执行
      shell编程语言的基本结构:
        各种系统命令的结合
        数据存储:变量、数组
        表达式:a+b(例)
        语句:if(例)

 

2、 脚本基本格式
  1> shell 脚本:包含一些命令或声明,并符合一定格式的文本文件
  格式要求:首行 shebang 机制

#!/bin/bash
#!/usr/bin/python
#!/usr/bin/perl

  2> 脚本规范,脚本代码开头约定:
    第一行一般为调用使用的语言(shebang 机制)
    程序名,避免更改文件名而无法找到正确的文件
    版本号
    更改时间
    作者相关信息
    该程序的作用,及注意事项
    最后是各版本的更新简要说明

  3> shell 脚本的用途有:
    自动化常用命令
    执行系统管理和故障排除
    创建简单的应用程序
    处理文本或文件

  4> 创建 shell 脚本
    第一步:使用文本编辑器来创建文本文件
      第一行必须包括 shell 声明序列#!/bin/bash
      添加注释,注释以#开头
    第二步:运行脚本
      给予执行权限,在命令行上指定脚本的绝对或相对路径;
      也可以给定执行权限后,更改 PATH 路径,加入 PATH 变量直接执行;
      直接运行解释器,将脚本作为解释器程序的参数运行;
           # bash test.sh 或 # cat test.sh | bash(即使没有执行权限也能执行);
      放到网站目录下(/var/www/html/hello.sh)
        # curl http://ip_address/hello.sh | bash  #调用远程主机的程序,在本机执行

  5> 脚本测试:
    脚本之中命令有误,不影响后续命令的执行;而语法有误,则停止程序运行
    # bash -n test.sh  #检查语法是否错误
    # bash -x test.sh  #跟踪调试执行

[root@centos7 ~]#vim hello.sh
[root@centos7 ~]#cat hello.sh
#!/bin/bashecho "hello"
echo "my hostname is `hostname`"
[root@centos7 ~]#ll hello.sh -rw-r--r-- 1 root root 179 4月 1 20:02 hello.sh [root@centos7 ~]#bash -n hello.sh [root@centos7 ~]#bash -x hello.sh + echo hello hello ++ hostname + echo my hostname is centos7.localdomain my hostname is centos7.localdomain [root@centos7 ~]#bash hello.sh hello my hostname is centos7.localdomain [root@centos7 ~]#chmod +x hello.sh [root@centos7 ~]#ll hello.sh -rwxr-xr-x 1 root root 179 4月 1 20:02 hello.sh [root@centos7 ~]#./hello.sh hello my hostname is centos7.localdomain

 

3、变量
  字符串在内存中存存储以二进制进行存储、寻找,而我们使用变量 NAME="字符串",来访问该字符串。也可以重新定义字符串,重新画一块地址空间存放新字符串,指针指向新字符串的内存空间,原来的内存空间也在但是可以回收了。
  name="变量"  #变量可以为字符串、`命令`、变量、文件

[root@centos7 ~]#name="zhangsan"
[root@centos7 ~]#echo $name
zhangsan
[root@centos7 ~]#hn=`hostname`
[root@centos7 ~]#echo $hn
centos7.localdomain

  shell 不分数据类型,都认为是字符串

  变量:命名的内存空间
    数据存储方式:
      字符:
      数值:整型、浮点型

  变量:变量类型
    作用:
      1> 数据存储格式
      2> 参与的运算
      3> 表示的数据范围
    类型:
      字符:
      数值:整型、浮点型
    强类型:变量不经过强制转换,它永远是这个数据类型,不允许隐式的类型转换。一般定义变量时必须指定类型、参与运算必须符合类型要求,调用未声明变量会产生错误。
      如 java,c
    弱类型:语言的运行时会隐式做数据类型转换。无须指定类型,默认均为字符型,参与运算会自动进行隐式类型转换,变量无须事先定义可直接调用。
      如:bash 不支持浮点数,php

  变量命名法则:
    1> 不能使用程序中的保留字:例如 if,for
    2> 只能使用数字、字母及下划线,且不能以数字开头
    3> 见名知意
    4> 统一命名规则:驼峰命名法

编写脚本/root/bin/systeminfo.sh,显示当前主机系统信息:包括主机名、IPv4 地址、操作系统版本、内核版本、CPU 型号、内存大小、硬盘大小
# hostname 命令,显示当前主机名
# ifconfig 命令,加正则表达式,截取ipv4地址
# cat /etc/redhat-release 命令,查看操作系统版本
# uname -r 命令,查看内核版本
# lscpu 命令,显示cpu型号
# free -h 或 cat /etc/proc/meminfo 命令,查看内存大小
# lsblk 命令,查看硬盘大小

[root@centos7 ~]#cat systeminfo.sh 
#!/bin/bashecho "my hostname is `hostname`"
echo "ipv4:`ip a | grep "inet" | grep "/24" | tr -s ‘ ‘ | cut -d ‘ ‘ -f 3 | cut -d ‘/‘ -f 1`"
echo "Operating system version:`cat /etc/redhat-release`"
echo "Kernel nersion:`uname -r`"
# 型号 即 Model
echo "CPU`lscpu | grep "型号:" | tr -s ‘ ‘`"
echo "RAM SIZE:`free -h | grep "Mem" | tr -s ‘ ‘ | cut -d ‘ ‘ -f 2`"
echo "DISK SIZE:`lsblk | grep "^sda" | tr -s ‘ ‘ | cut -d ‘ ‘ -f 4`"
[root@centos7 ~]#./systeminfo.sh my hostname is centos7.localdomain ipv4:192.168.100.111 Operating system version:CentOS Linux release 7.4.1708 (Core) Kernel nersion:3.10.0-693.el7.x86_64 CPU型号: 142 RAM SIZE:976M DISK SIZE:20G

 

1.请编写脚本 /root/bin/backup.sh , 实现每日将 /etc/ 目录备份到 /root/目录下,以 etc 加 YYYY-mm-dd 时间格式命名
  #!/bin/bash
  echo -e "\e[1;31mstart backup...\e[0m"
  sleep 2
  cp -a /etc/ /data/etcbak/etc`date +%F`
  echo -e "\e[1;31mbackup is finished.\e[0m"
2.
编写脚本 /root/bin/disk.sh,显示当前硬盘分区中空间利用率最大的值(相关命令:df -h;grep;tr;cut···)
3.编写脚本/root/bin/links.sh,显示正连接本主机的每个远程主机的 IPv4 地址和连接数,并按连接数从大到小排序

  bash 中变量的种类:
    局部变量:生效范围为当前 shell 进程;对当前 shell 之外的其他 shell 进程,包括当前 shell 的子进程均无效
    环境(全局变量):生效范围为当前 shell 进程及其子进程
    本地变量:生效范围为当前 shell 进程中某代码片断,通常指函数
    位置变量:在脚本中调用通过命令行传递给脚本的参数(脚本后跟参数实现不同功能)
      $1,$2,…:对应第 1、第2...参数
      $0:命令本身(针对同一程序创建不同软链接,$0 值不同则实现不同功能)
      $*:传递给脚本的所有参数,全部参数合为一个字符串
      $@:传递给脚本的所有参数,每个参数为独立字符串
      $#:传递给脚本的参数个数
      $@ $*只在被双引号包起来才会有差异(脚本调用的时候)
      set --清空所有位置变量
    特殊变量:$?,$0,$*,$@,$#,$$(当前进程的进程编号),$PPID(父进程的进程 ID)
    只读变量:只能声明,但不能修改和删除
    声明只读变量:
      readonly name
      declare -r name
     查看只读变量:
      readonly -p

  ()的使用,()里的命令只执行这一次,一次性的,实质是开启了一个子进程。

# (umask 026;touch /data/f1)
#ll /data/f1
-rw-r-----. 1 root root 0 25 14:08 /data/f1
# umask
0022

    针对于变量也是一样。
    { command; }影响当前进程

# x=1;echo "pid=$$";(echo "subpid=$$";echo "subx=$x";x=2;echo "subx2=$x");echo $x    #小括号的使用
pid=2157
subpid=2157
subx=1
subx2=2
1

 

[root@192 bin]#name="zhang"    //定义局部变量
[root@192 bin]#echo $name
zhang
[root@192 bin]#export name     //设置全局变量等同于 export name="zhang"

env 或 export 或 declare -x //显示环境变量 set //显示系统自带变量和自定义变量 显示最全 unset name //删除 name 变量

 

请实现拷贝脚本,拷贝本机文件至远程主机:
例:
#!/bin/bash
echo -e "\e[1;31menter password to start copying\e[0m"
scp $* root@192.168.129.142:/root/ #$*指传递脚本的参数
echo -e "\e[1;31mcopy is finished.\e[0m"

 

  shift 命令:
  参数队列:1 2 3 4 5... 1 2 3... 2 3 4...(先处理 1,1 处理完 2 补位)可以配合循环使用。

[root@centos7 bin]#vim shift.sh 
[root@centos7 bin]#cat shift.sh 
#!/bin/bash
$@
echo "$#"
shift
echo "$#"
shift
echo "$#"
shift
echo "$#"
[root@centos7 bin]#shift.sh 1 2 3 4
/root/bin/shift.sh:行8: 1: 未找到命令
4
3
2
1

 

  退出状态:
    进程使用退出状态来报告成功或失败
    0 代表成功,1-255 代表失败
    $? 变量保存最近的命令退出状态
  例如:

[root@centos7 bin]#ping -c -1 www.abidu.com &>/dev/null;echo $?
2

  退出状态码:(bash 自定义退出状态码)
  exit [n]:自定义退出状态码
  注意:脚本中一旦遇到 exit 命令,脚本会立即终止;终止退出状态取决于 exit 命令后面的数字
  注意:如果未给脚本指定退出状态码,整个脚本的退出状态码取决于脚本中执行的最后一条命令的状态码

 

linux—shell脚本编程

上一篇:ubuntu16.04安装mmdetection


下一篇:mac安装指定版本node