Linux 就该这么学 CH04 VIM编辑器和Shell命令脚本
0 概述
1 Vim编辑器
在linux 中一切都是文件,而配置一个服务就是修改其配置文件的参数。
vim 编辑器有三种模式:命令模式,末行模式和编辑模式。
命令模式:控制光标移动,对文件进行操作。
末行模式:保存或退出文档,以及设置编辑环境。
编辑模式:对文本进行编辑。
1) 编辑文档
a:在光标后一位插入。
i:在光标当前位置插入。
o:在光标下一行插入。
:wq保存退出。
:wq!强制保存退出。
2)配置主机名称
在linux系统中主机名称一般保存在 /etc/hostname.
查看主机名称命令: hostname
3) 配置网卡信息
RHEL7中网卡配置文件是以ifcfg开头的。再加上网卡名称就是网卡的配置文件了。
网卡配置步骤:
- 用vim 打开 /etc/sysconfig/network-scripts/ifcfg-xxx的网卡文件,修改文件使其包含至少下面几项(其他的可以不变,注释可以不要):
TYPE=Ethernet #设备类型
BOOTPROTO=static #地址分配模式
NAME=eno16777736 #网卡名称
ONBOOT=yes #是否启动
IPADDR=192.168.10.10 #IP 地址
NETMASK=255.255.255.0 #子网掩码
GATEWAY=192.168.10.1 #网关地址
DNS1=192.168.10.1 #DNS 地址
配置网卡IP的命令是:
[root@RHEL Desktop]# ifconfig eno16777736 192.168.2.10 netmask 255.255.255.0
- 重启网卡并测试网络是否联通(ping之后使用ctrl -c 来强制停止)。
[root@RHEL Desktop]# systemctl restart network
[root@RHEL Desktop]# ping 192.168.2.10
PING 192.168.2.10 (192.168.2.10) 56(84) bytes of data.
64 bytes from 192.168.2.10: icmp_seq=1 ttl=64 time=0.061 ms
64 bytes from 192.168.2.10: icmp_seq=2 ttl=64 time=0.064 ms
64 bytes from 192.168.2.10: icmp_seq=3 ttl=64 time=0.047 ms
4) 配置YUM软件仓库。
yum仓库的作用是为了进一步简化RPM管理软件的难度以及自动分析所需软件包及其依赖关系的技术。
搭建并配置yum仓库的步骤如下:
- cd到/etc/yum.repos.d/ 目录中(该目录存放yum的配置文件)。
[root@RHEL Desktop]# cd /etc/yum.repos.d/
- 使用Vim 创建一个rhel7.repo的新配置文件(名称可变,后缀必须为.repo),写入下面文件黑体文件并退出。
[root@RHEL yum.repos.d]# vim rhel7.repo
rhel7.repo内容如下:
name=rhel7
baseurl=file:///media/cdrom
enabled=1
gpgcheck=0
- 按照配置参数的路径挂载光盘,并把光盘挂载信息写入到/etc/fstab文件中。
[root@RHEL yum.repos.d]# mkdir -p /media/cdrom
[root@RHEL yum.repos.d]# mount /dev/cdrom /media/cdrom
mount: /dev/sr0 is write-protected, mounting read-only
[root@RHEL yum.repos.d]# vim /etc/fstab
在fstab文件的最后一行后面添加下面信息
/dev/cdrom /media/cdrom iso9660 defaults 0 0
- 使用yum install httpd -y来检查yum是否可用,如果最后出现complete则代表正确。
[root@RHEL yum.repos.d]# yum install httpd
Loaded plugins: langpacks, product-id, subscription-manager
This system is not registered to Red Hat Subscription Management. You can use subscription-manager to register.
Resolving Dependencies
--> Running transaction check
---> Package httpd.x86_64 0:2.4.6-17.el7 will be installed
...
...
Complete!
2 编写shell脚本
shell脚本命令的工作方式有两种:交互式和批量式。
交互式为输入一个命令立即执行。批量式是先写一个shell脚本文件,再一次性执行该脚本文件内的命令。
1)编写简单的脚本
把linux命名按顺序依次写入到一个文件中,这就是一个简单的脚本文件。
例如:
上图第一行是新建或打开example.sh 脚本。不在脚本文件内容内。
第二行是 脚本声明(#!)告诉系统使用哪种shell解释器来执行该脚本。
第三行#是解释,可以对脚本进行简单的说明。
接下面是脚本的主要内容,也是执行的命令。
两种运行脚本的方法:
1.使用解释器命令运行脚本:bash xx.sh
[root@RHEL Desktop]# bash example.sh
/root/Desktop
total 76
drwxr-xr-x. 3 root root 4096 Aug 29 21:06 .
dr-xr-x---. 16 root root 4096 Aug 29 21:02 ..
drwxr-xr-x. 3 root root 4096 Aug 26 22:38 a
2.使用完整的路径运行脚本: ./xx.sh
但是该方法需要获得先特殊权限。
[root@RHEL Desktop]# ./example.sh
bash: ./example.sh: Permission denied
[root@RHEL Desktop]# chmod u+x example.sh
[root@RHEL Desktop]# ./example.sh
/root/Desktop
total 76
drwxr-xr-x. 3 root root 4096 Aug 29 21:06 .
dr-xr-x---. 16 root root 4096 Aug 29 21:02 ..
chmod u+x example.sh 是改变权限命令,后面会讲到。 u=用户, x =执行。
2)接收用户参数
Linux已经内设了用于接收参数的变量,变量之间可以使用空格间隔。
一些默认的常用的特殊变量的意义:
$0 代表 当前shell的脚本名称。
$#代表总共有几个参数。
$* 代表所有位置的参数值。
$? 代表上一次命令执行的返回值。执行成功则返回0,否则返回非0值。
$1,$2…代表第N个位置的参数。
修改example.sh的内容如下:
#!/bin/bash
#for example by root
pwd
#ls -al
echo "The result of execution of the previous command is $?"
echo "the current sh file name is $0 "
echo "total have $# parameters,there are $*"
echo "the 1st parameter is $1,the 2nd parameter is $2"
执行结果如下:
[root@RHEL Desktop]# bash example.sh 1 2 3
/root/Desktop
The result of execution of the previous command is 0
the current sh file name is example.sh
total have 3 parameters,there are 1 2 3
the 1st parameter is 1,the 2nd parameter is 2
[root@RHEL Desktop]#
3) 判断用户的参数
接着学习如何进一步处理用户的参数。
shell脚本的条件测试语法可以判断表达式是否成立,若条件成立则返回数字0,不成立则返回非0. 结果存放在 $?中。
条件测试格式:
按照测试对象来划分,条件测试语句分为4中。
- 文件测试语句。
- 逻辑测试语句。
- 整数值比较语句。
- 字符串比较语句。
文件测试即使用指定条件来判断文件是否存在使用权限不足等情况的运算符。参数如下:
$? 显示上一条命令执行后的返回值。
下面判断/etc/fstab是不是一个文件。
[root@RHEL Desktop]# [ -e /etc/fstab ] | echo $?
0
逻辑语句用于对测试结果进行逻辑分析,根据测试结果可实现不同的效果。
逻辑与 (&&) :表示前面命令执行成功之后才会执行后面的结果。
逻辑或 (||):表示前面命令执行不成功后才会执行它的结果。
逻辑非 (!):表示把条件测试的结果取反。
[root@RHEL Desktop]# [ $USER=root ] && echo "root" || echo "user"
root
[root@RHEL Desktop]# [ ! $USER=root ] && echo "root" || echo "user"
user
整数比较运算符只对数字进行操作,不能将数字与字符或文件进行混合操作。而且大于等于小于不能使用 > = < ,而是使用字母。
[root@RHEL7 Desktop]# [ 3 -gt 5 ]
[root@RHEL7 Desktop]# echo $?
1
注意: 上面两个不能用管道符连写,结果会出错。原因不详???
下面的命令用来判断当前linux系统的内存是否小于1G。
[root@RHEL7 Desktop]# FREEMEM=`free -m | grep -i mem | awk '{ print $4 }'`
[root@RHEL7 Desktop]# [ $FREEMEM -gt 1024 ] && echo "this is OK." || echo "this is not OK."
this is OK.
注意第一条命令当中最外面使用的是 ``(反引号)。
3 流程控制语句
1) if 语句
if 语句用于条件测试判断,有单分支,双分支和单分支之分。
单分支格式:
if 条件
then
执行语句
fi
例程,判断一个目录是否存在,如果不存在则新建该目录。
[root@RHEL7 Desktop]# vim if1.sh
#!/bin/bash
#test if
DIR="a/b"
if [ ! -e $DIR ]
then
mkdir -p $DIR
fi
[root@RHEL7 Desktop]# ls
if1.sh petalinux
[root@RHEL7 Desktop]# bash if1.sh
[root@RHEL7 Desktop]# ls
a if1.sh petalinux
双分支格式
if 条件
then
执行语句1
else 执行语句2
fi
例程,判断一个IP是否在线。
[root@RHEL7 Desktop]# vim if2.sh
#!/bin/bash
#test if else
ping -c 3 -i 0.2 -W 3 $1 &> /dev/null
if [ $? -eq 0 ]
then
echo "the host $1 is on line."
else echo "the host #1 is off-line."
fi
[root@RHEL7 Desktop]# bash if2.sh 192.168.2.10
the host #1 is off-line.
对 ping -c 3 -i 0.2 -W 3 $1 &> /dev/null
的解释:
-c指定ping的次数。
-i 指定ping 的间隔。
-W 指定等待的最大时间。
&> /dev/null 将输出结果。不管正确与否,都输出到null中。
/dev/null 是一个没有回收功能的垃圾桶。
多分支格式:
if 条件1
then
执行语句1
elif 条件2
then
执行语句2
else 执行语句3
fi
例程:下面根据输入的数字来判断成绩怎么样。
使用了外部读取的命令: read。 -p选项是输出提示信息。
[root@RHEL Desktop]# vim vchkscore.sh
#!/bin/bash
# test if elif else
read -p "Enter your score(0-100) : " GRADE
if [ $GRADE -ge 85 ] && [ $GRADE -le 100 ]
then
echo "$GRADE is excellent !"
elif [ $GRADE -ge 70 ] && [ $GRADE -le 84 ]
then
echo "$GRADE is pass."
else echo "$GRADE is fail. "
fi
# end
[root@RHEL Desktop]# bash vchkscore.sh
Enter your score(0-100) : 98
98 is excellent !
[root@RHEL Desktop]# bash vchkscore.sh
Enter your score(0-100) : 20
20 is fail.
2) for语句
for循环语句允许脚本一次性读取多个信息,然后逐一对信息进行操作处理,当要处理的数据有范围时,使用for循环最好。
格式:
for 变量名 in 取值列表
do
执行命令
done
例程:
用for循环批量建立用户。
新建一个name的文件,里面放用户名称,然后写一个脚本文件,来批量建立这些用户。
[root@RHEL Desktop]# vim users.txt
andy
barry
carl
duke
tom
[root@RHEL Desktop]# vim for_example.sh
#!/bin/bash
#test for function
read -p "Enter the users passwd: " PASSWD
for UNAME in `cat users.txt`
do
id $UNAME &> /dev/null
if [ $? -eq 0 ]
then
echo "Already exists."
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
[root@RHEL Desktop]# bash for_example.sh
Enter the users passwd: 111
andy ,create success
barry ,create success
carl ,create success
duke ,create success
tom ,create success
例程:
删除刚才建立的用户。
[root@RHEL Desktop]# vim del_users.sh
#!/bin/bash
#delect users
for UNAME in `cat users.txt`
do
id $UNAME &> /dev/null
if [ $? -eq 0 ]
then
userdel -rf $UNAME
id $UNMAE &> /dev/null
if [ $? -eq 0 ]
then
echo "delect $UNAME successful."
else
echo "delect $UNAME failed."
fi
else
echo "the user not exist."
fi
done
[root@RHEL Desktop]# bash del_users.sh
delect andy successful.
delect barry successful.
delect carl successful.
delect duke successful.
delect tom successful.
3)while 循环语句
while循环语句是根据某些条件来重复执行的命令,它的循环结构往往在执行前并不能确定最终的次数。
格式:
while 条件测试
do
执行的命令
done
$RANDOM变量
$RANDOM变量来调取一个随机的数值(范围0-32767)。
$RANDOM %1000 则是取0-999之间的随机数。
expr 命令
expr命令是一个手工命令行计数器,用于在UNIX/LINUX下求表达式变量的值,一般用于整数值,也可用于字符串。
语法
expr 表达式
表达式说明:
用空格隔开每个项;
用 / (反斜杠) 放在 shell 特定的字符前面;
对包含空格和其他特殊字符的字符串要用引号括起来
实例
1、计算字串长度
> expr length “this is a test”
14
2、抓取字串
> expr substr “this is a test” 3 5
is is
3、抓取第一个字符数字串出现的位置
> expr index "sarasara" a
2
4、整数运算
> expr 14 % 9
5
> expr 10 + 10
20
> expr 1000 + 900
1900
> expr 30 / 3 / 2
5
> expr 30 \* 3 (使用乘号时,必须用反斜线屏蔽其特定含义。因为shell可能会误解显示星号的意义)
90
> expr 30 * 3
expr: Syntax error
let命令
let 命令是 BASH 中用于计算的工具,用于执行一个或多个表达式,变量计算中不需要加上 $ 来表示变量。如果表达式中包含了空格或其他特殊字符,则必须引起来。
自加操作:let no++
自减操作:let no–
简写形式 let no+=10,let no-=20,分别等同于 let no=no+10,let no=no-20。
例程:
猜数字游戏。猜一个0-999之间的数。
运行结果:
[root@RHEL Desktop]# bash guess.sh
the price is 0-9999,guess it:
please enter you answer:500
too low.
please enter you answer:800
too high.
please enter you answer:650
too low.
please enter you answer:720
too high.
please enter you answer:670
too low.
please enter you answer:690
too high.
please enter you answer:680
too high.
please enter you answer:675
too high.
please enter you answer:673
congratulate, the price is 673.
you total guess 9 times.
注意 :***=两边不要有空格。***
case 条件测试语句
case语句是在多个范围内匹配数据。
格式为:
case 变量值 in
条件1)
执行语句1
;;
条件2)
执行语句2
;;
*)
默认执行语句
esac
例程:判断输入的是字母,数字还是其他的。
[root@RHEL7 Desktop]# vim case_example.sh
#!/bin/bash
#test case
read -p "please enter a key:" KEY
case $KEY in
[a-z]|[A-Z] )
echo "your input is a letter"
;;
[0-9] )
echo "your input is a digit"
;;
* )
echo "your input is others"
;;
esac
[root@RHEL7 Desktop]# bash case_example.sh
please enter a key:3
your input is a digit
[root@RHEL7 Desktop]# bash case_example.sh
please enter a key:a
your input is a letter
[root@RHEL7 Desktop]# bash case_example.sh ,
please enter a key:,
your input is others
[root@RHEL7 Desktop]#
4 计划任务服务
计划任务是在指定的时间端自动的启用或者停止某项服务命令,从而实现运维的自动化。
创建一次性的任务
at命令
at 时间:建立一次性任务。 ctrl +d 来结束任务的建立。
at -l : 查看一次性任务
atrm 任务号 : 删除一次性任务
at -c 任务编号 :查看某个具体的任务。
[root@RHEL Desktop]# at 23:00
at> systemctl restart fttpd
at> systemctl restart sshd
at> <EOT> #这里使用ctrl+d 来结束。
job 1 at Tue Sep 3 23:00:00 2019
[root@RHEL Desktop]# at 23:00
at> <EOT>
job 2 at Tue Sep 3 23:00:00 2019
[root@RHEL Desktop]# at 23:30
at> reboot
at> <EOT>
job 3 at Tue Sep 3 23:30:00 2019
[root@RHEL Desktop]# at -l
1 Tue Sep 3 23:00:00 2019 a root
2 Tue Sep 3 23:00:00 2019 a root
3 Tue Sep 3 23:30:00 2019 a root
[root@RHEL Desktop]# at -c 1
#!/bin/sh
# atrun uid=0 gid=0
# mail root 0
.....
${SHELL:-/bin/sh} << 'marcinDELIMITER12f598ee'
systemctl restart fttpd
systemctl restart sshd
marcinDELIMITER12f598ee
[root@RHEL Desktop]# atrm 2
[root@RHEL Desktop]# at -l
1 Tue Sep 3 23:00:00 2019 a root
3 Tue Sep 3 23:30:00 2019 a root
创建周期性的任务
crond服务用于执行周期性的任务。
crontab
crontab -e : 创建,编辑计划任务。
crontab -l :查看某条计划任务。
crontab -r :删除某条计划任务。
crontab -u :来编辑他人的计划任务。需要root身份登录。
crond服务设置任务的参数格式是: 分 时 日 月 星期 命令。
其中:
1、分钟 必须有数字,绝对不能为空或者*。
2、日和星期不能同时有,否则冲突。
3、命令必须带有路径,不能是直接的命名。如 /bin/tar 。
4、逗号,可以表示多个时间或时间段。 减号- 可以表示一段连续的时间。
5、除号/表示执行的时间间隔,如 “*/2” 表示每隔2分钟执行一次。
whereis 查看命令
[root@RHEL Desktop]# whereis reboot
reboot: /usr/sbin/reboot /usr/share/man/man2/reboot.2.gz /usr/share/man/man8/reboot.8.gz
其中/usr/sbin/reboot 是reboot的路径。
[root@RHEL7 ~]# crontab -e
25 3 * * 1,3,5 /usr/sbin/reboot
0 */2 29 2 * /usr/bin/touch log.txt
crontab: installing new crontab
[root@RHEL7 ~]# crontab -l
25 3 * * 1,3,5 /usr/sbin/reboot
0 */2 29 2 * /usr/bin/touch log.txt
[root@RHEL7 ~]# crontab -r
[root@RHEL7 ~]# crontab -l
no crontab for root
[root@RHEL7 ~]#