第4章 Vim编辑器与Shell命令脚本
vim文本编辑器
vim编辑器有三种模式:命令模式,末行模式和编辑模式。
命令模式:控制光标移动,可对文本进行复制、粘贴、删除和查找等工作。 输入模式:正常的文本录入。 末行模式:保存或退出文档,以及设置编辑环境 |
在每次运行Vim编辑器时,默认进入命令模式,此时需要先切换到输入模式后再进行文档编写工作,而每次在编写完文档后需要先返回命令模式,然后再进入末行模式,执行文档的保存或退出操作。在Vim中,无法直接从输入模式切换到末行模式。
vim中常用的命令:
命令 |
作用 |
dd |
删除(剪切)光标所在整行 |
5dd |
删除(剪切)从光标处开始的5行 |
yy |
复制光标所在整行 |
5yy |
复制从光标处开始的5行 |
n |
显示搜索命令定位到的下一个字符串 |
N |
显示搜索命令定位到的上一个字符串 |
u |
撤销上一步的操作 |
p |
将之前删除(dd)或复制(yy)过的数据粘贴到光标后面 |
a键与i键分别是在光标后面一位和光标当前位置切换到输入模式,而o键则是在光标的下面再创建一个空行
末行模式主要用于保存或退出文件,以及设置Vim编辑器的工作环境,还可以让用户执行外部的Linux命令或跳转到所编写文档的特定行数。要想切换到末行模式,在命令模式中输入一个冒号就可以了。末行模式中可用的命令如下:
命令 |
作用 |
:w |
保存 |
:q |
退出 |
:q! |
强制退出(放弃对文档的修改内容) |
:wq! |
强制保存退出 |
:set nu |
显示行号 |
:set nonu |
不显示行号 |
:命令 |
执行该命令 |
:整数 |
跳转到该行 |
:s/one/two |
将当前光标所在行的第一个one替换成two |
:s/one/two/g |
将当前光标所在行的所有one替换成two |
:%s/one/two/g |
将全文中的所有one替换成two |
?字符串 |
在文本中从下至上搜索该字符串 |
/字符串 |
在文本中从上至下搜索该字符串 |
编写shell脚本
Shell基础
Shell作为用户与Linux系统内部的通信媒介,除了能够支持各种变量与参数外,还提供了诸如循环、分支等高级编程语言才有的控制结构特性。Shell脚本命令的工作方式有两种:交互式和批处理。
l 交互式(Interactive):用户每输入一条命令就立即执行。
l 批处理(Batch):由用户事先编写好一个完整的Shell脚本,Shell会一次性执行脚本中诸多的命令
Shell脚本文件的名称可以任意,但为了避免被误以为是普通文件,建议将.sh后缀加上,以表示是一个脚本文件。
通常情况下,shell脚本可以分为三个部分:
第一部分(第一行):脚本声明(#!),用来告诉系统使用哪种shell解释器来执行该脚本
第二部分(从第二行开始):脚本注释信息,是对脚本功能和某些命令的介绍信息
第三部分:脚本主体,用来具体实现功能
接收用户参数
Linux系统已经内设了用于接收参数的变量,变量之间可以使用空格间隔。
l $0 对应的是当前Shell脚本程序的名称
l $# 对应的是总共有几个参数
l $* 对应的是所有位置的参数值
l $? 对应的是显示上一次命令的执行返回值
l $1、$2、$3……则分别对应着第N个位置的参数值
测试
Shell支持测试命令,用于测试表达式的条件真假,如果测试条件为真,则返回0值,否则返回非0值,它是判断语句和循环语句中条件测试的工具。测试命令的结构如下:
test expression |
或者
[ expression ] |
其中条件expression是一个表达式,它可以由数字、字符串、文本和文本属性比较,同时可以加入算术、字符串、文本等运算符
注意:使用“[ expression ]”这种方式时,“[”后和“]”前分别有一个空格。这种方式经常与if、case和while语句连用,用做流程控制语句的判断条件。
条件测试语句可以分为四种:
l 文件测试语句
l 逻辑测试语句
l 整数值比较语句
l 字符串比较语句
文件测试即使用指定条件来判断文件是否存在或权限是否满足等情况的运算符
操作符 |
作用 |
-d |
测试文件是否为目录类型 |
-e |
测试文件是否存在 |
-f |
判断是否为一般文件 |
-r |
测试当前用户是否有权限读取 |
-w |
测试当前用户是否有权限写入 |
-x |
测试当前用户是否有权限执行 |
逻辑语句用于对测试结果进行逻辑分析,根据测试结果可实现不同的效果。例如在Shell终端中逻辑“与”的运算符号是&&,它表示当前面的命令执行成功后才会执行它后面的命令;逻辑“或”,它在Linux系统中的运算符号为||,表示当前面的命令执行失败后才会执行它后面的命令;逻辑语句“非”,在Linux系统中的运算符号是一个叹号(!),它表示把条件测试中的判断结果取相反值
整数比较运算符仅是对数字的操作,不能将数字与字符串、文件等内容一起操作,而且不能想当然地使用日常生活中的等号、大于号、小于号等来判断。因为等号与赋值命令符冲突,大于号和小于号分别与输出重定向命令符和输入重定向命令符冲突。
操作符 |
作用 |
-eq |
是否等于 |
-ne |
是否不等于 |
-gt |
是否大于 |
-lt |
是否小于 |
-le |
是否等于或小于 |
-ge |
是否大于或等于 |
字符串比较语句用于判断测试字符串是否为空值,或两个字符串是否相同。它经常用来判断某个变量是否未被定义(即内容为空值)
操作符 |
作用 |
= |
比较字符串内容是否相同 |
!= |
比较字符串内容是否不同 |
-z |
判断字符串内容是否为空 |
流程控制语句
l If条件测试语句
if条件语句的单分支结构由if、then、fi关键词组成:
#!/bin/bash
DIR="/media/cdrom"
if [ ! -e $DIR ]
then
mkdir -p $DIR
fi
if条件语句的双分支结构由if、then、else、fi关键词组成:
#!/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
if条件语句的多分支结构由if、then、else、elif、fi关键词组成:
l for循环条件语句
for循环条件语句的语法如下:
l while条件循环语句
l case条件测试语句
case条件测试语句和switch语句的功能非常相似!case语句是在多个范围内匹配数据,若匹配成功则执行相关命令并结束整个条件测试;而如果数据不在所列出的范围内,则会去执行星号(*)中所定义的默认命令
计划任务服务程序
计划任务分为一次性计划任务与长期性计划任务
l 一次性计划任务
一次性计划任务只执行一次,用于临时性工作需求,命令为“at”,示例:
[root@linuxprobe ~]# at 23:30
at > systemctl restart httpd
at > <Ctrl+d>(结束编写计划任务)
job 3 at Mon Apr 27 23:30:00 2015
l 周期性任务
创建、编辑计划任务的命令为“crontab -e”,查看当前计划任务的命令为“crontab -l”,删除某条计划任务的命令为“crontab -r”
简单示例,没分钟写入一次日期到log.log文件:
* * * * * date >> /tmp/shell/log.log
第5章用户身份与文件权限
用户身份与能力
创建用户useradd
useradd命令用于创建新的用户,格式为“useradd[选项] 用户名”。使用该命令创建用户账户时,默认的用户家目录会被存放在/home目录中,默认的Shell解释器为/bin/bash,而且默认会创建一个与该用户同名的基本用户组
参数 |
作用 |
-d |
指定用户的家目录(默认为/home/username) |
-e |
账户的到期时间,格式为YYYY-MM-DD. |
-u |
指定该用户的默认UID |
-g |
指定一个初始的用户基本组(必须已存在) |
-G |
指定一个或多个扩展用户组 |
-N |
不创建与用户同名的基本用户组 |
-s |
指定该用户的默认Shell解释器 |
可以用“id 用户名”查看用户id,用户基本组id和用户所属扩展组
创建用户组groupadd
groupadd命令用于创建用户组,格式为“groupadd[选项] 群组名”。为了能够更加高效地指派系统中各个用户的权限,在工作中常常会把几个用户加入到同一个组里面,这样便可以针对一类用户统一安排权限
修改用户属性usermod
usermod命令用于修改用户的属性,格式为“usermod[选项] 用户名”。
参数 |
作用 |
-c |
填写用户账户的备注信息 |
-d -m |
参数-m与参数-d连用,可重新指定用户的家目录并自动把旧的数据转移过去 |
-e |
账户的到期时间,格式为YYYY-MM-DD |
-g |
变更所属用户组 |
-G |
变更扩展用户组 |
-L |
锁定用户禁止其登录系统 |
-U |
解锁用户,允许其登录系统 |
-s |
变更默认终端 |
-u |
修改用户的UID |
示例,将用户Cain加入root用户组:
usermod -G root Cain
要再删除可以用gpasswd命令:
Gpasswd -d Cain root
修改用户密码passwd
passwd命令用于修改用户密码、过期时间、认证信息等,格式为“passwd [选项] [用户名]”。普通用户只能使用passwd命令修改自身的系统密码,而root管理员则有权限修改其他所有人的密码。root管理员在Linux系统中修改自己或他人的密码时不需要验证旧密码
参数 |
作用 |
-l |
锁定用户,禁止其登录 |
-u |
解除锁定,允许用户登录 |
--stdin |
允许通过标准输入修改用户密码,如echo "NewPassWord" | passwd --stdin Username |
-d |
使该用户可用空密码登录系统 |
-e |
强制用户在下次登录时修改密码 |
-S |
显示用户的密码是否被锁定,以及密码所采用的加密算法名称 |
删除用户userdel
userdel命令用于删除用户,格式为“userdel[选项] 用户名”。如果我们确认某位用户后续不再会登录到系统中,则可以通过userdel命令删除该用户的所有信息。在执行删除操作时,该用户的家目录默认会保留下来,此时可以使用-r参数将其删除。
文件权限与归属
Linux系统中用不同的符号区分不同类型的文件:
-:普通文件。 d:目录文件。 l:链接文件。 b:块设备文件。 c:字符设备文件。 p:管道文件。 |
每个文件都有所属的所有者和所有组,并且规定了文件的所有者、所有组以及其他人对文件所拥有的可读(r)、可写(w)、可执行(x)等权限
文件的特殊权限
在复杂多变的生产环境中,单纯设置文件的rwx权限无法满足我们对安全和灵活性的需求,因此便有了SUID、SGID与SBIT的特殊权限位
SUID
SUID是一种对二进制程序进行设置的特殊权限,可以让二进制程序的执行者临时拥有属主的权限
SGID
SGID主要实现如下两种功能:
l 让执行者临时拥有属组的权限(对拥有执行权限的二进制程序进行设置);
l 在某个目录中创建的文件自动继承该目录的用户组(只可以对目录进行设置)。
chmod -Rf g+s testdir/
SBIT
设置了SBIT特殊权限位,除非是该目录的所有者,否则无法删除这里面的文件。
chmod -R o+t linux/
文件的隐藏属性
chattr
chattr命令用于设置文件的隐藏权限,格式为“chattr[参数] 文件”。如果想要把某个隐藏功能添加到文件上,则需要在命令后面追加“+参数”,如果想要把某个隐藏功能移出文件,则需要追加“-参数”
参数 |
作用 |
i |
无法对文件进行修改;若对目录设置了该参数,则仅能修改其中的子文件内容而不能新建或删除文件 |
a |
仅允许补充(追加)内容,无法覆盖/删除内容(Append Only) |
S |
文件内容在变更后立即同步到硬盘(sync) |
s |
彻底从硬盘中删除,不可恢复(用0填充原文件所在硬盘区域) |
A |
不再修改这个文件或目录的最后访问时间(atime) |
b |
不再修改文件或目录的存取时间 |
D |
检查压缩文件中的错误 |
d |
使用dump命令备份时忽略本文件/目录 |
c |
默认将文件或目录进行压缩 |
u |
当删除该文件后依然保留其在硬盘中的数据,方便日后恢复 |
t |
让文件系统支持尾部合并(tail-merging) |
x |
可以直接访问压缩文件中的内容 |
lsattr命令
lsattr命令用于显示文件的隐藏权限,格式为“lsattr[参数] 文件”。在Linux系统中,文件的隐藏权限必须使用lsattr命令来查看,平时使用的ls之类的命令则看不出端倪
文件访问控制列表
如果希望对某个指定的用户进行单独的权限控制,就需要用到文件的访问控制列表(ACL)了。基于普通文件或目录设置ACL其实就是针对指定的用户或用户组设置文件或目录的操作权限。另外,如果针对某个目录设置了ACL,则目录中的文件会继承其ACL;若针对文件设置了ACL,则文件不再继承其所在目录的ACL。
setfacl命令
setfacl命令用于管理文件的ACL规则,格式为“setfacl[参数] 文件名称”。文件的ACL提供的是在所有者、所属组、其他人的读/写/执行权限之外的特殊权限控制,使用setfacl命令可以针对单一用户或用户组、单一文件或目录来进行读/写/执行权限的控制。其中,针对目录文件需要使用-R递归参数;针对普通文件则使用-m参数;如果想要删除某个文件的ACL,则可以使用-b参数。文件的权限最后一个点(.)变成了加号(+),这就意味着该文件已经设置了ACL了
setfacl -Rm u:Cain:rwx /root
getfacl命令
getfacl命令用于显示文件上设置的ACL信息,格式为“getfacl文件名称”
su命令与sudo服务
su命令可以解决切换用户身份的需求,使得当前用户在不退出登录的情况下,顺畅地切换到其他用户,比如从root管理员切换至普通用户。
su命令与用户名之间可以有一个减号(-),这意味着完全切换到新的用户,即把环境变量信息也变更为新用户的相应信息,而不是保留原始的信息。强烈建议在切换用户身份时添加这个减号(-)
sudo命令用于给普通用户提供额外的权限来完成原本root管理员才能完成的任务,格式为“sudo [参数] 命令名称”。sudo命令可以把特定命令的执行权限赋予给指定用户,这样既可保证普通用户能够完成特定的工作,也可以避免泄露root管理员密码。
参数 |
作用 |
-h |
列出帮助信息 |
-l |
列出当前用户可执行的命令 |
-u 用户名或UID值 |
以指定的用户身份执行命令 |
-k |
清空密码的有效时间,下次执行sudo时需要再次进行密码验证 |
-b |
在后台执行指定的命令 |
-p |
更改询问密码的提示语 |
可以使用sudo命令提供的visudo命令来配置用户权限。这条命令在配置用户权限时将禁止多个用户同时修改sudoers配置文件,还可以对配置文件内的参数进行语法检查,并在发现参数错误时进行报错
每次执行sudo命令后都会要求验证一下密码。虽然这个密码就是当前登录用户的密码,但是每次执行sudo命令都要输入一次密码其实也挺麻烦的,这时可以添加NOPASSWD参数,使得用户执行sudo命令时不再需要密码验证:
[root@linuxprobe ~]# visudo
96 ##
97 ## Allow root to run any commands anywhere
98 root ALL=(ALL) ALL
99 linuxprobe ALL=NOPASSWD: /usr/sbin/poweroff