主要内容

  1. Vim 文本编辑器
  2. 编写 Shell 脚本
  3. 流程控制语句
  4. 计划任务服务程序

Vim 文本编辑器

1
在 Linux 中,一切都是文件,而配置一个服务就是在修改器配置文件的参数。
  1. 三种模式
    • 命令模式:控制光标移动,对文本进行复制、粘贴、删除和查找等操作
    • 输入模式:正常的文本录入
    • 末行模式:保存或退出文档,以及设置编辑环境
  2. 流程
    • 每次运行 Vim,默认是命令模式
    • 先切换(aio)输入模式进行文本编写
    • 然后(esc)返回命令模式
    • 再进入(:)末行模式进行保存或退出
    • 无法从输入模式直接切换到末行模式
  3. Vim 常用命令
    序号命令作用
    1dd删除(剪切)光标所在整行
    25dd删除(剪切)从光标处开始的5行
    3yy复制光标所在整行
    45yy复制从光标处开始的 5 行
    5n搜索结果,下一个
    6N搜索结果,上一个
    7u撤销上一步的操作
    8p将之前删除(dd)或复制的(yy)的数据粘贴到光标后
  4. 末行模式
    • 输入:即可进入该模式
    • 该模式主要用于保存或退出文件
    • 设置 Vim 编辑器的工作环境
    • 让用户执行外部的 Linux 命令
    • 跳转指定的行数
      序号命令作用
      1:w保存
      2:q退出
      3:q!放弃对文档的修改,强制退出
      4:wq!强制保存退出
      5:set nu显示行号
      6:set nonu不显示行号
      7:命令执行输入的命令,包括外部命令
      8: 整数跳转指定行
      9:s/one/two将当前光标所在行的第一个 one 替换成 two
      10:s/one/two/g将当前光标所在行的所有 one 替换成 two
      11:%s/one/two/g将全文中的所有 one 替换成 two
      12:/字符串在文本中从上至下搜索该字符串
      13:?字符串在文本中从上至下搜索该字符串

编写简单文档

命令模式切换输入模式

  • a:append,在光标后一位进行输入
  • i:insert,在光标前一位进行输入
  • o:换行输入

配置主机名称

配置网卡信息

注:笔者用的 Centos 7.5,虚拟机,与原著作者书中的案例不同

配置 Yum 软件仓库

关于 Yum,笔者会另起一篇文章。

编写 Shell 脚本

  • 交互式(Interactive):输入一条,执行一条
  • 批处理(Batch):实现编写好一个完整的脚本,一次执行脚本中的诸多命令

编写简单 Shell 脚本

1
2
3
4
5
6
7
8
9
10
11
12
vim simple.sh

# ---------- 输入
#!/bin/bash
pwd
ls -la

# 赋予权限
chmod u+x simple.sh

# 执行
./simple.sh

接受用户输入参数

  • $0 标识脚本名称
  • $# 标识参数数量
  • $n 位置 N 的参数值
  • $* 所有参数
  • $? 显示上一次命令的执行返回值
  • 案例:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    vim simple_input.sh

    # 输入
    #!/bin/bash
    echo "当前脚本名称 $0"
    echo "一共有 $# 个参数,分别是 $*"
    echo "第一个参数是 $0,第二个参数是$3"
    ~

    # 权限
    chmod u+x simple_input.sh

    # 执行
    ./simple_input.sh 1 2 3 4

    # 输出
    # 当前脚本名称 ./simple_input.sh
    # 一共有 4 个参数,分别是 1 2 3 4
    # 第一个参数是 ./simple_input.sh,第二个参数是3

判断用户参数

  • Shell 脚本中的条件测试语法可以判断表达式是否成立,若条件成立则返回数字 0,否则便返回其他随机数值
  • 格式:[ 条件表达式 ]
    • 注意:中括号的边上有一个空格,务必保留
  • 结果:
    • 0 为真
    • > 0 为假,具体值可能为1,可能为2,具体看系统版本(原著,笔者环境为 1)
  • 分类:
    • 文件测试语句
    • 逻辑测试语句
      • && 与运算
      • ! 非运算
      • || 或运算
    • 整数值测试语句
    • 字符串比较语句

文件测试语句

序号运算符作用
1-d测试文件是否为目录类型
2-e测试文件是否存在
3-f测试是否为一般文件
4-r测试当前用户是否有权限读取
5-w测试当前用户是否有权限写入
6-x测试当前用户是否有权限执行

案例:

1
2
3
# && 与操作,|| 或操作,失败后执行
# 其他的运算符与之类似
[ -e file ] && echo "Exist" || echo "Not Exist"

整数值测试语句

序号运算符作用
1-eq是否等于
2-ne是否不等于
3-gt是否大于
4-lt是否小于
5-le是否等于或小于
6-ge是否等于或大于

案例一:

1
2
3
4
# 其他的运算符与之类似
[ 10 -eq 110 ]
echo $?
# 真 0,假 1

案例二:

1
2
3
4
5
6
7
# 获取内存余量,判断是否充足(余量 < 1024M)

# 获取内存余量
# 务必注意:FreeMem 后面的等号左右两边不要有空格
FreeMem=`free -m | grep Mem: | awk '{print $4}'`
# 判断比较
[ $FreeMem -lt 1024 ] && echo "内存不足" || echo "内存充足"

字符串比较语句

序号运算符作用
1=比较字符串是否相同
2!=比较字符串是否不同
3-z判断字符串是否为空

案例一:

1
2
3
# 判断 String 是否为空
[ -z $String ]
echo $?

案例二:

1
2
3
echo $LANG
# 运算符前后 务必 保留空格
[ $LANG != "en.US" ] && echo "Not en.US" || echo $LANG

流程控制语句

一共有四种 ifforwhilecase

if 语句

  • 单分支结构

    • 语法

      1
      2
      3
      if 条件测试操作
      then 命令序列
      fi
    • 案例:检查并创建目录

      1
      2
      3
      4
      5
      vim sample_check_dir.sh    
      # 赋予权限
      chmod u+x ./sample_check_dir.sh
      # 执行
      ./sample_check_dir.sh
      脚本:sample_check_dir.sh
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      # 输入一下内容:
      #!/bin/bash
      DIR="/root/fileTest/fileTestDeep"
      # 判断目录是否存在
      if [ ! -e $DIR ]; then
      # 创建测试目录
      mkdir -p $DIR
      # 列出目录文件
      ls /root
      fi
  • 双分支结构

    • 语法:

      1
      2
      3
      4
      if 条件测试操作
      then 命令序列1
      else 命令序列2
      fi
    • 案例:

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      # 编辑
      vim sample_check_host.sh
      # 赋予权限
      chmod u+x ./sample_check_host.sh

      # 执行
      # Please input host.
      ./sample_check_host.sh
      # Host 127.0.0.1 is On-line.
      ./sample_check_host.sh 127.0.0.1
      # Host 256.0.0.1 is Off-line.
      ./sample_check_host.sh 256.0.0.1
      脚本:sample_check_host.sh
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      #!/bin/bash
      # 判断是否输入了测试 ip
      if [ ! -z $1 ]
      then
      ping -c 3 -i 0.2 -W 3 $1 &> /dev/null
      if [ $? -eq 0 ]; then
      echo "Host $1 is On-line."
      else
      echo "Host $1 is Off-line."
      fi
      else echo "Please input host."
      fi
  • 多分支结构

    • 语法

      1
      2
      3
      4
      5
      6
      7
      if 条件测试操作1
      then 命令序列1
      elif 条件测试操作2
      then 命令序列2
      else
      命令序列3
      if
    • 案例

      1
      2
      3
      4
      5
      6
      7
      # 编辑
      vim sample_check_score.sh
      # 赋予权限
      chmod u+x ./sample_check_score.sh

      # 执行
      ./sample_check_score.sh
      脚本:sample_check_score.sh
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      #!/bin/bash

      # 读入成绩
      read -p "输入你的成绩:" GRADE

      # 分支判断
      if [ $GRADE -ge 85 ] && [ $GRADE -le 100 ]; then
      echo "$GRADE 分 非常棒"
      elif [ $GRADE -ge 70 ] && [ $GRADE -le 84 ]; then
      echo "$GRADE 分 通过"
      elif [ $GRADE -ge 100 ] || [ $GRADE -le 0 ]; then
      echo "分数不合法"
      else
      echo "$GRADE 分 未通过"
      fi

for 语句

  • 语法

    1
    2
    3
    for 变量名 in 取值列表; do
    命令序列
    done
  • 案例

    脚本:sample_check_host_loop.sh
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    #!/bin/bash

    # 从文件读取 hostlist
    HOST_LIST=$(cat /root/ip_addrs.txt)
    # 循环 ping
    for host in $HOST_LIST; do
    ping -c 3 -i 0.2 -W 3 $host &> /dev/null
    if [[ $? -eq 0 ]]; then
    echo "Host $host is On-line"
    else
    echo "Host $host is Off-line"
    fi
    done

while 语句

  • 语法

    1
    2
    3
    while [[ 条件测试操作 ]]; do
    命令序列
    done
  • 案例

    脚本:sample_game_guess_number.sh
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    #!/bin/bash

    PRICE=$(expr $RANDOM % 1000)
    TIMES=0

    echo "猜猜看数字是多少"
    while true; do
    read -p "请输入您猜的数字:" PRICE_IN
    let TIMES++
    if [[ $PRICE_IN -eq $PRICE ]]; then
    echo "正确数字 $PRICE,一共猜了 $TIMES 次"
    exit 0
    elif [[ $PRICE_IN -gt $PRICE ]]; then
    echo "大了一些"
    else
    echo "小了一些"
    fi
    done

case 语句

  • 语法

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    case 变量值 in
    模式1 )
    命令序列1
    ;;
    模式2 )
    命令序列2
    ;;
    *)
    默认命令序列
    esac
  • 案例

    脚本:sample_check_char.sh
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    #!/bin/bash

    read -p "输入一个字符:" KEY

    case $KEY in
    [a-z]|[A-Z] )
    echo "字母"
    ;;
    [0-9] )
    echo "数字"
    ;;
    *)
    echo "其他种类字符"
    esac

计划任务服务程序

  • 一次性任务

    • 命令:at
    • 注意
      • at: 未找到命令:执行 yum install at
      • No atd running?:执行 systemctl start at
    • 参数
      序号运算符作用
      1-f指定包含具体指令的任务文件
      2-q指定新任务的队列名称
      3-l 或 atq显示待执行任务的列表
      4-d 或 atrm删除指定的待执行任务
      5-m任务执行完成后向用户发送E-mail
    • 案例
      案例at
      1
      2
      3
      4
      5
      6
      at 12:30
      > /bin/ls
      > ctrl+d 结束输入

      # 执行后,会提示:您在 /var/spool/mail/root 中有新邮件
      # 邮件就是 命令的执行结果
  • 周期性任务

    • 命令:crontab
    • 注意
      • 在 crond 服务的配置参数中,可以像 Shell 脚本那样以#号开头写上注释信息,方便阅读理解
      • 计划任务中的 “minute” 字段必须有数值,绝对不能为空或是*号
      • “day” 和 “week” 字段不能同时使用,否则就会发生冲突。
    • 说明:系统默认安装,自动启动 crond 进程,每分钟检测。
    • 格式:minute hour day month week command,顺序:分 时 日 月 周

      运算符作用
      minute表示分钟,可以是从 0 到 59 之间的任何整数
      hour表示小时,可以是从 0 到 23 之间的任何整数
      day表示日期,可以是从 1 到 31 之间的任何整数
      month表示月份,可以是从 1 到 12 之间的任何整数
      week表示星期几,可以是从 0 到 7 之间的任何整数,这里的 0 或 7 代表星期日
      command要执行的命令,可以是系统命令,也可以是自己编写的脚本文件

      在以上各个字段中,还可以使用以下特殊字符:
      字符作用
      *代表所有可能的值
      例如 month 字段是星号,则表示在满足其它字段的制约条件后每月都执行该命令操作
      ,可以用逗号隔开的值指定一个列表范围
      例如,“1,2,5,7,8,9”
      -可以用整数之间的中杠表示一个整数范围
      例如 “2-6” 表示 “2,3,4,5,6”
      /可以用正斜线指定时间的间隔频率
      例如 “0-23/2” 表示每两小时执行一次。
      --------
      同时正斜线可以和星号一起使用
      例如 */10,如果用在 minute 字段,表示每十分钟执行一次。
    • 命令选项

      序号运算符作用
      1-e编辑该用户的计时器设置
      2-l列出该用户的计时器设置
      3-r删除该用户的计时器设置
      4-u<用户名称>指定要设定计时器的用户名称
    • 案例:
      案例crontab
      1
      2
      3
      4
      5
      6
      7
      8
      # 每 1 分钟执行一次 command
      * * * * * command
      # 每小时的第 3 和第 15 分钟执行
      3,15 * * * * command
      # 每小时执行任务
      * */1 * * * command
      # 一月一号的 4 点执行任务
      0 4 1 jan * command

附录

  1. Shell 脚本调试的三种方式

写在最后

版本内容时间
v1.0.01. 创建文档
2. 第四章阅读笔记草稿
2018-09-18 22:08:06
v1.0.11. 继续编写第四章阅读笔记草稿2018-10-12 16:28:21
v1.0.21. 第四章阅读笔记完成,并完成校验2018-10-13 17:20:47