RHEL7--第四章
- vim文本编辑器
三种模式:
命令模式:运行vim时,默认进入命令模式;可对文本进行复制、粘贴、删除和查找;
编辑模式:文本录入
末行模式:保存退出等,运行命令;
三种模式之间的切换:

从上图可知,“输入模式”与“末行模式”之间无法直接切换,必须回到命令模式再切换;
命令模式命令:
o: 在光标所在行的下面新建一行,并进入编辑模式;
dd: 删除(剪切)光标所在整行;
5dd: 删除(剪切)从光标所在起的向下 5 行,包括光标行;
yy: 复制光标所在整行;
5yy: 复制从光标所在行起到的向下 5 行,包括光标行;
p: 将之前删除(dd)或复制(yy)过的数据粘贴到光标所在行的下一行;
P: 将之前删除(dd)或复制(yy)过的数据粘贴到光标所在行的上一行;
u: 撤销上一步的操作;
n: 显示搜索命令定位到的下一个字符串;
N: 显示搜索命令定位到的上一个字符串;
G: 跳转至最后一行;
#G: 跳转至指定#的行,#表示数字;
gg: 第一行;
末行模式命令:
:q 退出;
:q! 强制退出(放弃对文档的修改内容);
:x 保存退出;
:wq 保存退出;
:wq! 强制保存退出;
:set nu 显示内容行号;
:set nonu 不显示内容行号;
:数字 当文本显示行号后,光标跳转到指定行号
:!命令 在vim编辑窗内执行命令,无需退出vim;
:s/A/B 将当前光标所在行的第一个 A 替换成 B;
:s/A/B/g 将当前光标所在行的所有的 A 替换成 B;
:%s/A/B/g 将全文中所有的 A 都替换成 B;
?字符串 在文本中从下至上搜索该字符串;配合命令模式中的 n,N 使用;
/字符串 在文本中从上至下搜索该字符串;配合命令模式中的 n,N 使用;
:w /PATH/TO/SOMEWHERE 当前文本保存另存到其他路径;
- 配置主机名称
配置方法永久生效:
CentOS 7 如下:
1:# vim /etc/hostname
2:# echo 主机名 > /etc/hostname
CentOS 6 如下:
1:# vim /etc/sysconfig/network
HOSTNAME=主机名
2:# hostname 主机名 立即临时生效;
- 配置网卡信息
CentOS 7 里面的网卡名称改成 enoxxxxx 格式;也有 ensfxxxx 格式;
en 代表 enthernet 以太网;
o 代表 onboard 内置网卡;主板自带;
xxxx 代表 编号唯一性,迁移系统不会出错;
sf 代表 外加的网卡;
TYPE=Ethernet 网卡类型
BOOTPROTO=static 网络地址协议:dhcp,static
DEFROUTE=yes
PEERDNS=yes
PEERROUTES=yes
IPV4_FAILURE_FATAL=no
NAME=eno16777736
UUID=c6b064f4-2850-4b28-bb8b-718960a3ac0f
DEVICE=eno16777736 网卡名称
ONBOOT=yes 开机自动启用网口
IPADDR=192.168.30.100 IP地址
NETMASK=255.255.255.0 掩码
- 编写shell脚本
shell解释器:
人与计算机硬件之间的翻译官,用户与linux系统内部的通信媒介;
shell脚本命令的工作方式:
交互式(Interactive):用户每输入一条命令就立即执行;
批处理(Batch):用户事先编写好一个完整的shell脚本,一次性执行脚本中诸多命令;
shell脚本包含:
命令,正则表达式,管道符,数据重定向,逻辑语句等
- 编写简单的脚本
简单编写:
[root@aaa~]# vim example.sh
#!/bin/bash
#For test BY xxxx
pwd
ls -al
第一行: #! 脚本声明,来告诉系统使用哪个 shell解释器 来执行脚本;
第二行: #For test BY xxxx 注释符表示对脚本功能的介绍,让人了解这个脚本的作用;
第三行,四行:可执行语句即为命令;
运行脚本:
方法1:使用 bash 直接运行 shell 脚本
#bash example.sh
方法2:输入绝对路径方式来执行,但是脚本必须要有执行权限;
#chmod u+x example.sh
#./example.sh . 为绝对路径
- 接受用户的参数
让脚本程序能够像执行命令时那样,接受用户输入的参数;

shell脚本已有内设的接受参数的变量如下,变量之间空格间隔;
$0: 对应是当前shell脚本的名称;
$#: 对应是总共有几个参数;
$*: 对应是所有位置的参数值;
$?: 对应显示上一次命令的执行回值;
$1,$2....:分别对应第N个参数值;
举例:
编辑脚本:
[root@aaa~]#vim example.sh

运行脚本:
# bash example.sh /etc/fstab a b c d e

解析命令:
/etc/fstab a b c d e :用户输入的参数,让 example.sh 脚本接受
运行结果最后一行 0:表示 $?显示上一次命令执行成功与否的回值,0表示成功;即 wc -l `echo $1`这条命令运行成功了;
- 判断用户的参数
shell脚本中的条件测试语法可以判断表达式是否成立,成立返回数字0,否则返回其他随机数值。
条件测试语法的执行格式:切记,条件表达式两边均有一个空格;

按照测试对象来划分,条件测试语句可分为4中;
文件测试语句;
逻辑测试语句;
整数值比较语句;
字符串比较语句;
1:文件测试语句
使用指定条件来判断文件是否存在或权限是否满足情况的运算符;
-d 测试文件是否为目录类型;
-e 测试文件是否存在;
-f 判断是否为一般文件;
-r 测试当前用户是否有 读取权限;
-w 测试当前用户是否有 写入权限;
-x 测试当前用户是否有 执行权限;
举例:
判断 /etc/fstab 是否是一个目录类型的文件;
# [ -d /etc/fstab ] [ ] 两边都必须有空格;
# echo $?
1 解析:条件判断错误,返回除了0以外的随机数值;
# [ -f /etc/fstab ]
# echo $?
0 解析:条件判断成立,返回值为 0;
2:逻辑测试语句
对测试结果进行逻辑分析,根据测试结果可实现不同的效果;
逻辑语句分三种;
&&:表示 与
||: 表示 或
!: 感叹号表示 非
例1:
shell终端中逻辑 "与" 的运算符号是 &&,它表示当 &&前面的命令执行成功后才会执行 &&后面的命令;
# [ -e /dev/cdrom ] && echo "yes"
yes
解析:测试/dev/cdrom是否存在,yes 表示/dev/cdrom文件存在;
例2:
shell终端中逻辑 "或" 的运算符号是 ||,它表示当 ||前面的命令执行失败后才会执行 ||后面的命令;
[root@aaa~]# echo $USER
root
[root@aaa~]# [ $USER = root ] || echo "hello"
解析:$USER 显示为当前系统登录用户的环境变量,由于前面[ ]等式成立,所以不执行后面的 echo hello 命令;
[root@aaa~]# su - user1
[user1@aaa~]$ echo $USER
user1
[user1@aaa~]$ [ $USER = root ] || echo "hello"
hello
解析:切换用户,$USER 环境变量改变,[ ]等式不成立,执行echo hello;
例3:
shell终端中逻辑 "非" 的运算符号是 !,条件测试中的判断结果取相反值;即测试结果正确,变成错误的,原本测试结果错误的,变成正确;
[root@aaa~]# [ $USER != root ] || echo "hello"
hello
解析:原本 $USER = root 等式成立,加了 ! ,取相反结果:不成立;||出现,运行 echo "hello" ;
例4:
三种逻辑语句用同时出现:
[root@aaa~]# [ $USER != root ] && echo "yes" || echo "no"
no
解析:当前登录用户为root,先用逻辑"非",取反结果,则"与"无法成立,执行 "或" 的结果为 no ;
3:整数值比较语句
注意:整数比较运算符仅对数字操作,无法将数字与字符串、文件等一起操作;日常中的等号与赋值命令冲突,大于号小于号与输出输入重定向命令符冲突皆不能使用;
可用的整数比较运算符:
-eq 是否等于;
-ne 是否不等于;
-gt 是否大于;
-lt 是否小于;
-le 是否等于或小于;
-ge 是否等于或大于;
例1:
# [ 10 -gt 10 ]
# echo $?
1
例2:
# free -m
查看系统内存信息,并以 M 为单位显示;
# free -m | grep Mem | awk '{print $4}'
显示关键字Mem的内存信息,并打印出来;
# FreeMem=`free -m | grep Mem | awk '{print $4}'`
设置变量名FreeMem,并赋值为命令回执;
# [ $FreeMem -lt 1024 ] && echo yes || echo no
比较变量FreeMem的值是否小于1024,成立显示yes,错误显示no;
4:字符串比较语句
判断测试字符串是否为空值,或两个字符串是否相同;通常用来判断某个变量是否被定义,即内容为空值;
常见字符串比较运算符:
= 比较字符串内容是否相同;
!= 比较字符串内容是否不同;
-z 判断字符串内容是否为空;
例1:
# [ -z $ABC ]
# echo $?
0
解析:在添加变量时,使用上述命令来判断变量名是否已经被使用了;
例2:
# echo $LANG
en_US.UTF-8
# [ $LANG != aaa ] && echo yes
或 # [ $LANG != "aaa" ] && echo yes
yes
解析:比较$LANG环境变量的内容是否与 aaa 不同,不同则运行 echo yes;
- 流程控制语句
四种流程控制语句:
if、for、while、case;
1:if条件测试语句(一次性)
可以让脚本根据实际情况自动执行相应命令;
if语句分为3种:
A:单分支结构;
由 if、then、fi 关键词组成,只在条件成立后才执行预设命令;

例1:
[root@aaa~]#vim mkcdrom.sh
#!/bin/bash
DIR="/media/cdrom"
if [ ! -e $DIR ]
then
mkdir -p $DIR
fi
解析:
if [ ! -e $DIR] ,首先 if语句必须条件成立后才执行预设命令;也就是 [ ! -e $DIR]出的结果成立,运行命令mkdir,不成立直接结束脚本;
if 语句条件成立的意思:[ ]得出的结果特指有=正为成立,没有=负为不成立;是为成立,不是为不成立,以此类推;比如,有这个文件夹,没有这个文件夹;
[ ! -e $DIR]:中的感叹号,即为逻辑语句中的"非",取反向结果;
B:双分支结构;
由 if、then、else、fi 关键词组成,进行一次条件匹配判断,如果与条件匹配,则执行预设命令;反之则执行不匹配的预设命令;如果...那么...或者...那么;

例1:
[root@aaa~]#vim chkhost.sh
#!/bin/bash
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
[root@aaa~]#bash chkhost.sh 192.168.1.1
Host 192.168.1.1 is off-line.
解析:
1):ping 的参数解释;
-c:规定ping尝试的次数;-c 3
-i:定义每个数据包的发送间隔;-i 0.2
-w:定义等待超时时间;-w 3
2):$1 &> /dev/null
$1:前面讲过,shell内设的接受参数,表示脚本后面的第一个参数;
&>:表示标准输出和错误输出重定向到同一个文件;
/dev/null:表示黑洞文件,吞噬一切,输出重定向指向此文件表示不显示任何信息;
C:多分支结构;
由 if、then、else、elif、fi 关键词组成,进行多次条件匹配判断,多次判断中的任何一项在匹配成功后执行相应的预设命令;如果..那么..如果..那么..;

例1:
[root@aaa~]#vim chkscore.sh
#!/bin/bash
read -p "Enter your score (0-100): " GRADE
if [ $GRADE -ge 85 ] && [ $GRADE -le 100 ]
then
echo "$GRADE is nice"
elif [ $GRADE -ge 70 ] && [ $GRADE -le 84 ]
then
echo "$GRADE is pass"
else
echo "$GRADE is fail"
fi
# bash chkscore.sh
Enter your score (0-100):88
88 is nice
解析:
1):read 命令 记得多看
从键盘读取赋予变量的值,通常在shell脚本中与用户进行交互的场合,该命令可以一次读取多个变量的值,变量和输入的值都需要空格隔开;
-p:指定变量读取值时的提示符;
-t:指定变量读取值时等待的时间(秒);
2):read -p "Enter your score (0-100): " GRADE
使用 read 命令给变量名GRADE添加变量值时,增加提示符 "Enter your score (0-100):";
3):else
表示为不满足以上条件的其他任意情况,都属于else;比如输入值1000时,也会提示 "1000 is fail";
4):&&
同时满足左右两侧的条件;
2:for条件循环语句(一次性)
允许脚本一次性读取多个信息,然后逐一对信息进行操作处理,当处理的数据有范围时,使用for循环语句最好。

例1:
# vi users.txt 提前创建用户名列表 a1 a2 b1 b2,必须每行输入;即取值列表;

[root@aaa~]#vim useraddtest.sh
#!/bin/bash
read -p "请输入用户密码:" PASSWD
for UNAME in `cat users.txt`
do
id $UNAME &> /dev/null
if [ $? -eq 0 ]
then
echo "$UNAME is existed"
else
useradd $UNAME &> /dev/null
echo $PASSWD | passwd --stdin $UNAME &> /dev/null
if [ $? -eq 0 ]
then
echo "$UNAME , Create success"
else
echo "$UNAME , Create failure"
fi
fi
done
解析:
1):for UNAME in `cat users.txt`
UNAME为变量名,UNAME循环从cat users.txt的内容中赋值;如UNAME=a1,UNAME=a2以此类推;
2):fi fi done
最后3个fi、fi、done的意思,先用 fi 结束if语句,然后 done 结束for语句;
3):do
开启循环测试;
例2:
结合之前的if语句和for语句,循环测试多个主机IP是否在线,脚本如下;
# vi ip.txt

[root@aaa~]#vim iptest.sh
#!/bin/bash
for IP in `cat ip.txt`
do
ping -c 3 -i 0.2 -w 3 $IP &> /dev/null
if [ $? -eq 0 ]
then
echo "$IP is online"
else
echo "$IP is offline"
fi
done
解析:
1):in 后面也可以跟变量,格式如下;
LIST=`cat ip.txt` 等同于 LIST=$(cat ip.txt)
for IP in $LIST
3:while条件循环语句(循环)
只需运行脚本一次后,循环执行脚本,直到满足条件,退出;
是一种让脚本根据某些条件来重复执行命令的语句,它的循环结构往往在执行前不确定最终执行的次数,完全不同于for循环语句中有目标、有范围的使用场景。while循环语句通过判断条件测试的真假来决定是否继续执行命令,条件为真继续执行,为假结束循环;

例1:
[root@aaa~]#vim guess.sh
#!/bin/bash
PRICE=$(expr $RANDOM % 1000)
TIMES=0
echo "商品实际价格为0-999之间,猜价格多少?"
while true
do
read -p "请输入猜测的价格:" INT
let TIMES++
if [ $INT -eq $PRICE ] ; then
echo "yes,实际价格 $PRICE"
echo "总共猜了 $TIMES 次"
exit 0
elif [ $INT -gt $PRICE ] ; then
echo "高了"
else
echo "低了"
fi
done
解析:
1):expr
求表达式变量的值,也是手工命令行计数器;
2):$RANDOM
生产随机值的变量
3):expr $RANDOM % 1000
表示 1000以内取一个随机数字;
4):while true
表达式的值一直为真,无限循环。当if语句满足条件后,输入exit 0,就可以结束循环;
5):let TIMES++
让TIMES变量值加1;
4:case条件测试语句
在多个范围内匹配数据,若匹配成功则执行相关命令并结束整个条件测试,如果数据不在所列出范围内,则去执行星符号: *) 中所定义的默认命令;

例1:
[root@aaa~]#vim checkkeys.sh
#!/bin/bash
read -p "请输入一个字符,回车确认:" KEY
case "$KEY" in
[a-z]|[A-Z])
echo "你输入的是字母"
;;
[0-9])
echo "你输入的是数字"
;;
*)
echo "你输入的是特殊字符"
esac
- 计划任务服务程序
在指定的时间自动启用或停止某些服务或命令,实现运维的自动化;
计划任务认为:一次性和长期性计划任务;
一次性计划任务:满足临时的工作需求;
at:实现命令;
-l:查看已设置但未执行的计划任务;
at 时间:添加一次性计划任务;
Ctrl+d结束编写计划任务;
# at 20:20
at > systemctl restart httpd
at > 输入Ctrl+d 保存结束编写计划任务;
按删除键出现乱码时,按住 Ctrl键再按删除键即可;
atrm 任务序号:删除计划任务;
# at -l 查看任务号
# atrm 1 删除1号任务
例1:
# echo "systemctl restart network" | at 20:20
利用管道符直接添加计划任务信息;
周期性计划任务:
利用系统默认启用的crond服务来实现;
crontab:实现命令
-e:创建、编辑计划任务;
-l:查看当前计划任务;
-r:删除整个计划任务,慎用!!!
-u:修改他人的计划任务,必须为 root用户;
/etc/crontab:配置文件;
配置计划时间的要求:

1):格式:"分 时 日 月 星期 命令";
2):各种时间之间用空格隔开;
3):设置周一,三,五,形式为:1,3,5 用逗号隔开;
4):设置连续时间 1-7;
5):" / "表示执行任务的间隔时间,如:*/2 ;
0 */3 * * * 表示每隔3小时执行一次;
6):执行命令必须以绝对路径方式写入;
如:绝对路径 /usr/bin/touch
7):时间 "分" 字段必须有数值,绝对不能为空或是 * 号,而 日 和 星期 字段不能同时使用,会冲突;
8):可在vim窗口中使用 :!find / -name command,查找command的绝对路径,不需要退出vim窗口;
例1:
# crontab -e
0 22 * * * /usr/bin/rm -rf /tmp/*
每天的22:00,自动删除tmp目录的文件;
例2:
# crontab -e -u user1
修改指定用户 user1 的计划任务;
浙公网安备 33010602011771号