Linux从入门到入土

前言:水平十分有限,仅仅是个人总结linux的入门知识,参考资料众多无法一一考证出处,如有侵权请联系删除!

并不能保证内容全部正确,请读者仔细甄别,如有错误欢迎批评指正。

一、绪论

1 什么是linux

Linux,全称GNU/Linux,是一种免费使用和自由传播的类UNIX操作系统,其内核由林纳斯·本纳第克特·托瓦兹于1991年10月5日首次发布,是一个基于POSIX的多用户、多任务、支持多线程和多CPU的操作系统。它支持32位和64位硬件。Linux继承了Unix以网络为核心的设计思想,是一个性能稳定的多用户网络操作系统。Linux有上百种不同的发行版,如基于社区开发的debian、archlinux,和基于商业开发的Red Hat Enterprise Linux、SUSE、Oracle Linux等。

今天各种场合都有使用各种Linux发行版,从嵌入式设备到超级电脑,并且在服务器领域确定了地位。开放源代码的Linux可以让知识延续下去,新兴的软件公司可以从开放源代码上快速、低价的创建专业能力,丰富市场的竞争,防止独霸软件巨兽的存在。个人使用很少有著作权问题,绝大多数都是免费使用,几乎无所谓盗版问题。

2 linux与linux内核

Linux严格来说是单指操作系统的内核,因操作系统中包含了许多用户图形接口和其他实用工具。如今Linux常用来指基于Linux的完整操作系统,内核则改以Linux内核称之。1991年,林纳斯·托瓦兹(Linus Benedict Torvalds),一名21岁的就读于芬兰赫尔辛基大学的计算机科学专业学生,基于一些简单的想法,打算编写一个操作系统内核。之后,许多人为这个项目贡献了代码。

  • 到1991年9月,Linux内核版本 0.01 在芬兰大学和研究网络(FUNET)的FTP服务器(ftp.funet.fi)上发布。它有10,239行代码。

  • 在1991年10月,0.02版本的内核发布了。

  • 1991年12月,0.11版本的内核发布。

  • 1994年3月14日,Linux内核1.0.0发布,共176,250行代码。

  • 1995年3月,Linux 内核1.2.0发布,共310,950行代码。

  • 1999年1月25日,发布Linux内核2.2.0(1,800,847行代码)

  • 1999年12月18日,允许 Linux 内核用于企业级机器

  • 2001年1月4日,发布 Linux 内核2.4.0(3,377,902行代码)

  • 2003年12月17日,发布 Linux 内核2.6.0(5,929,913行代码)

  • 从2004年开始,发布过程发生了变化,新的内核每隔2-3个月定期发布,编号为2.6.0、2.6.1,直到2.6.39。

  • 2011年7月21日,Torvalds宣布发布Linux内核3.0:“2.6.<大版本> 的日子过去了”。

  • 2013年6月发布的Linux内核版本3.10包含15,803,499行代码,而2015年6月发布的4.1版本已发展到超过1950万行代码,由近14000名程序员贡献。

按照传统商业软件开发的方式,截至2011年1月4日,使用当前的代码行,将花费约30亿美元(约22亿欧元),才能够重新开发Linux的内核。

3 安装和下载

以CentOS为例学习linux:在官网地址下载和安装系统。

二、Bash shell

Bash Shell是一个命令解释器,它在操作系统的最外层,负责用户程序与内核进行交互操作的一种接口,将用户输入的命令翻译给操作系统,并将处理后的结果输出至屏幕。当我们使用远程连接工具连接linux服务,系统则会给打开一个默认的shell,我们可在这个界面执行命令,使用Shell可以实现对Linux系统的大部分管理。

1 提示符

登录到linux之后,每条命令左边都有这些提示符。

命令行提示符

1
2
3
4
5
6
7
[root@localhost ~]# 
# root:当前登录用户
# @ :分隔符
# localhost:主机名称,可以通过hostname查看
# ~:当前用户所在家目录
# #:通常指超级管理员
# $: 普通用户

2 基础语法

bash shell有三部分组成:command [-options] [arguments]

1
2
3
4
5
6
7
8
9
10
11
# 命令      选项        参数
command [-options] [arguments]

#命令: 整条shell命令的主体
#选项: 用于调节命令的输出效果
#以 “-”引导短格式选项(单个字符),例如“-l”
#以“--”引导长格式选项(多个字符),例如“--color”
#多个短格式选项可以写在一起,只用一个“-”引导,例如“-al”
#参数: 命令操作的对象,如文件、目录名等
# 选项和参数可以出现位置调换,命令,选项,参数之间要至少有一个空格
# 命令必须开头, 选项和参数位置可以发生变化

3 命令快捷键

快捷键可以帮助我们大大提升工作效率。

1
2
3
4
5
6
7
8
9
10
11
12
13
Ctrl + a    #光标跳转至正在输入的命令行的首部
Ctrl + e #光标跳转至正在输入的命令行的尾部
Ctrl + c #终止前台运行的程序
Ctrl + d #在shell中,ctrl-d表示退出当前shell
Ctrl + z #将任务暂停,挂至后台
Ctrl + l #清屏,和clear命令一样
Ctrl + k #删除从光标到行末的所有字符
Ctrl + u #删除从光标到行首的所有字符
Ctrl + r #搜索历史命令最近的一条, 利用关键字,Tab建选中
Ctrl + w #按单词或空格进行向前删除
Ctrl + 左右键 #按单词或空格进行向前向后跳

#在命令行前加面加 "#" 则该命令不会被执行

4 命令补全

使用tab可以帮我们补全命令,也可以补全路径,在实际生产中tab补全往往是我们使用的最多的。

1
2
3
4
5
# 比如查看ip命令,在centos7以上没有,需要安装:yum install net-tools -y
[root@localhost ~]# if
if ifcfg ifconfig ifdown ifenslave ifstat ifup

# 输入if按tab,会提示if开头的命令供选择

本身不支持参数的补全,需要安装工具包

1
yum install bash-completion -y

安装完之后,新打开一个bash后就有效果了,tab支持参数补全。

5 历史命令history

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
[root@localhost ~]# history
1 ls
2 vi etc/sysconfig/network-scripts/ifcfg-ens33
3 ls
4 ls -a
5 cd etc
6 cd etc/
7 cd ..
8 cd..
9 cd ..
10 cd..
11 ls -a
12 cd etc/
13 ls
14 cd sysconfig\
15 ls
16 cd network-scripts
17 ls
[root@localhost ~]#

可以查看所有历史敲过的命令,使用!加命令对应的序号就可以重新执行某行。举例:

1
2
3
4
5
6
!13   # 相当于执行了13行ls命令
!! # 双叹号,执行上一条命令
!cat # 执行最后一次的cat开头的命令
history -w # 保存命令历史到历史文件,保存在家目录的.bash_history文件里
history -c # 清空命令历史记录, 不会清空文件中的记录
history -d 10 # 删除命令历史的第 10 行

三、文件管理

文件管理是对一个文件进行、创建、复制、移动、查看、编辑、压缩、查找、删除等等。linux一切皆文件,所有的修改最终都是对文件操作。

1 linux文件目录结构

几乎所有的计算机操作系统都是使用目录结构组织文件。一般使用树状的文件结构,所以该结构又被称为“目录树”。

windows的目录数据结构是森林,多根;linux是树,单根。

linux目录结构

  • /根目录,所有的文件都在它的下面
  • bin二进制可执行文件,这个目录存放着最经常使用的命令,如ls,yum等等
  • boot这里存放的是与系统启动相关的文件,包括一些连接文件以及镜像文件,linux内核文件也在这里
  • dev是Device(设备)的缩写,该目录下存放的是 Linux 的外部设备,在 Linux 中访问设备的方式和访问文件的方式是相同的
  • etc用来存放配置文件和子目录,包括yum/rpm安装的软件配置文件等等
  • home普通用户的家目录,在创建用户时,每个用户要有一个默认登录和保存自己数据的位置,就是用户的主目录,如用户bob的主目录就是 /home/bob
  • root系统管理员用户家目录
  • run是一个临时文件系统,存储系统启动以来的信息。当系统重启时,这个目录下的文件应该被删掉或清除。
  • sbin这里存放的是系统管理员使用的系统管理程序
  • tmp存放临时文件
  • usr是一个非常重要的目录,用户的很多应用程序和文件都放在这个目录下
  • var在系统运行后才会渐渐占用硬盘容量的目录,目录主要是常态性变动文件,包括缓存(cache)、登录文件(logfile)以及某些软件运行所产生的文件,包括程序文件(lock file,run file),或者例如Mysql数据库的文件等

下面分别来介绍一些根目录下常见的文件夹

1.1 usr目录

是一个非常重要的目录,相当于win系统的C:Windows,目录结构如下

usr目录结构

  • usr/bin/用户所用命令,根目录下的bin目录是软链接到这里的bin
  • usr/sbin/系统管理员命令,与用户相关,根目录下的sbin也是软链接这里的sbin
  • usr/etc/该目录用于存放配置文件
  • usr/local软件安装的目录,相当于C:Program files
  • usr/lib 所有可执行文件所需要的库文件,Glibc 32bit,类似于windows下的dll文件
  • usr/lib64所有可执行文件所需要的库文件,Glibc 64bit
  • usr/include各种头文件,编译文件等时需要使用
  • usr/games曾经包含游戏等文件,现在很少用到
  • usr/local本地系统管理员用来自由添加程序的目录

1.2 etc目录

存放的是配置文件。极其重要,所有服务的配置都在这个目录中,常用的有:

1
2
3
4
/etc/sysconfig/network-scripts/ifcfg-* # 网络配置文件
/etc/hostname # 系统主机名配置文件,主机名很重要,有些特殊服务要依赖主机名,没有主机名会报错起不来;修改了要重启:reboot
/etc/resolv.conf # dns客户端配置文件,域名解析服务器,一般我们不配置,因为网卡的配置好了,会覆盖掉它,网卡的优先级高
/etc/hosts # 本地域名解析配置文件,域名解析,先找自己的hosts,再去域名解析

1.3 var目录

存放一些常态性变动文件,比如缓存、日志、登陆文件等等。

1
2
# 查看用户登录登陆日志
cat /var/log/secure

1.4 dev目录

该目录下存放的是 Linux 的外部设备,比如硬盘,硬盘分区,光驱,等等。

1
2
3
4
5
6
7
/dev/sd # 硬盘设备
/dev/null # 黑洞设备,只进不出。类似于垃圾回收站
/dev/random # 生成随机数的设备
/dev/zero # 能源源不断的产生数据,类似于取款机

# 还有一些这种文件sda sdb sdc sda1 sdb4,它们是磁盘文件
# linux中磁盘文件叫sd,第一个硬盘叫a,第二个叫b,sda1表示第一个磁盘的第一个分区,sdb4:第二个硬盘的第四个分区(服务可以插很多硬盘)

1.5 proc目录

根目录下的proc是反映系统当前进程的实时状态,如对应的进程停止则/proc下对应目录则会被删除

1
2
3
4
ls /proc # 可以看到很多id号,pid号,进程号,唯一

# 如果进程被关闭,id号的文件夹就没了
# id号每次启动都不唯一,只有一个进程唯一,systemd 是进程号1的进程,所有进程都是基于它派生出来的

1.6 其他文件夹

1
2
3
4
5
6
7
8
/media # 提供设备的挂载点,媒体文件。linux新增了盘符,需要手动挂载,把光盘里的数据,挂载到media目录
mount /dev/cdrom /media/

/mnt # 提供设备的挂载点(同上)

/opt # 第三方工具,第三方软件默认安装的(mysql...)

/bin, /sbin, /lib, /lib64 # 这些文件都以软链接的形式链接到/usr/目录下

2 文件管理命令

2.1 创建文件

1
2
3
4
5
6
touch file              # 没有则创建,有则修改时间
touch file2 file3 # 创建两个文件
touch /home/od/file4 file5 # 绝对路径创建
touch file{a,b,c} # {}集合,等价 touch a b c
touch file{1..10} # 从1-10循环创建
touch file{a..z} # 从a-z循环创建

2.2 创建文件夹

1
2
3
4
5
# 选项:-v 显示详细信息  -p 递归创建目录
mkdir dir1 # 当前目录创建dir1文件夹
mkdir /home/od/dir1 /home/od/dir2 # 绝对路径创建两个文件夹
mkdir -v /home/od/{dir3,dir4} # -v参数 打印出详细信息;如果没有od则创建失败,大括号内写文件夹名字,写几个就创建几个
mkdir -pv /home/od/dir5/dir6 #-p 递归创建,如果没有od文件夹,则创建一个,没有dir5则创建一个,以此类推

2.3 删除

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 选项:-r: 递归 -f: 强制删除 -v: 详细过程
rm file.txt #删除文件, 默认rm存在alias别名,rm -i所以会提醒是否删除文件
rm -f file.txt #删除文件, 不提醒
rm -r dir/ #递归删除目录,会提示
rm -rf dir/ #强制删除目录,不提醒(尽量少用)

# 1.rm删除示例
mkdir /home/dir10
touch /home/dir10/{file2,file3,.file4}
rm -f /home/dir10/ # 不包括隐藏文件
ls /home/dir10/ -a

# 2.rm删除示例2
touch file{1..10}
touch {1..10}.pdf
rm -rf file* # 以file开头的全删
rm -rf *.pdf # 以.pdf结尾的删除

2.4 移动

1
2
3
4
5
6
7
8
9
10
mv file file1             #原地移动==改名,把file改名file1
mv file1 /tmp/ #移动文件至tmp目录
mv /tmp/file1 ./ #移动tmp目录的文件至当前目录
mv dir/ /tmp/ #移动整个dir目录至/tmp目录下

touch file{1..3}
mv file1 file2 file3 /opt/ #移动多个文件或至同一个目录

mkdir dir{1..3}
mv dir1/ dir2/ dir3/ /opt/ #移动多个文件夹至同一个目录

2.5 复制

1
2
3
4
5
6
7
8
9
#选项: -v:详细显示命令执行的操作 -r: 递归处理目录与子目录 -p: 保留源文件或目录的属性

cp file /tmp/file_copy #复制file到某个目录下
cp name /tmp/name11 #修改名称
cp file /tmp/ #不修改名称
cp -p file /tmp/file_p #-p保持原文件或目录的属性(权限、创建时间等)
cp -r /etc/ /tmp/ #复制目录需要使用-r参数, 递归复制
cp -rv /etc/hosts /etc/hostname /tmp #拷贝多个文件至一个目录
cp -rv /etc/{hosts,hosts.bak} # 把hosts复制一份,改名叫hosts.bak

2.6 查看文件内容

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#------cat 文件查看
cp /etc/passwd ./pass
cat pass #正常查看文件方式
cat -n pass #-n显示文件有多少行
cat -A pass #查看文件的特殊符号,比如文件中存在tab键
tac pass #倒序查看文件
cat >> test2.txt <<EOF # 可以输入内容,写入文件,以EOF结尾
ads
adf
EOF

#------less、more 文件查看,可以分页
less /etc/services #使用光标上下翻动,空格进行翻页,q退出
more /etc/services #使用回车上下翻动,空格进行翻页,q退出(有百分比)

#------head 文件查看,从头部开始
head pass #查看头部内容,默认前十行
head -n5 pass #查看头部5行,使用-n指定
ps aux | head -5 # 只看头部5个进程;ps aux查看进程

#------tail
tail pass # 查看文件尾部,默认10行
tail -20 /var/log/secure # 查看文件尾部20行
tail -f /var/log/messages # -f动态查看文件尾部的变化
tailf /var/log/messages # 查看文件尾部的变化
ps aux | tail -2 # 看尾部的2个进程

#------grep过滤文件内容
grep "^root" pass #匹配以root开头的行
grep "bash$" pass #匹配以bash结尾的行
grep -i "ftp" pass #忽略大小写匹配
grep -Ei "sync$|ftp" pass #匹配文件中包含sync结尾或ftp字符串
ps aux | grep ssh # 查看ssh进程是否运行

# ------上翻,下翻
control+b:下翻
control+f:上翻

2.7 文件的上传与下载

wget、curl联网下载文件

1
2
3
4
5
6
7
8
# 如果没有wget命令,首先需要安装
yum install wget -y
wget url地址 # 从远程下载到本地,默认下载到当前路径
wget -O /etc/yum/aaa.img url地址 # 参数-O 指定下载路径

# crul:浏览网络上资源,测试连通性,-o保存到本地
#选项: -O: 指定下载地址
curl -O /etc/yum/aaa.html https://www.baidu.com/

rz,sz上传下载文件

1
2
3
4
# 如果没有rz,sz命令,首先需要安装
yum install lrzsz -y
rz # 只能上传文件(最大不能超过4g)
sz /path/file # 只能下载文件

2.8 文件查找

文件查找

1
2
locate /etc/sh       #搜索etc目录下所有以sh开头的文件
locate -i /etc/sh #搜索etc目录下,所有以sh开头的文件,-i 忽略大小写

命令查找

1
2
3
4
5
6
7
8
which ls  # 查找ls命令的绝对路径

whereis ls # 查找命令的路径、帮助手册、等
whereis -b ls # 仅显示命令所在的路径,仅看二进制

# 对于内核相关的一些命令,用which whereis 是无法查询到的,需要使用type查询
type -a ls # 查看命令的绝对路径(包括别名)
type -a for

2.9 字符处理

在有些情况下,需要对应一个无序的文本文件进行数据的排序,使用sort进行排序。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
sort [OPTION]... [FILE]...
# -r:倒序 -n:按数字排序 -t:指定分隔符(默认空格) -k:指定第几列, 指定几列几字符(指定1,1 3.1,3.3)

#1.首先创建一个文件,写入一写无序的内容
cat >> file.txt <<EOF
b:3
c:2
a:4
e:5
d:1
f:11
EOF

#2.使用sort下面对输出的内容进行排序
sort file.txt
a:4
b:3
c:2
d:1
e:5
f:11

#结果并不是按照数字排序,而是按字母排序。
#可以使用-t指定分隔符, 使用-k指定需要排序的列。
# -t 指定分隔符,-k指定列,按第二列排序
sort -t ":" -k2 file.txt
d:1
f:11 #第二行是11,因为按照ascii码进行排序
c:2
b:3
a:4
e:5

#按照排序的方式, 只会看到第一个字符,11的第一个字符是1, 按照字符来排序确实比2小。
#如果想要按照数字的方式进行排序, 需要使用 -n参数,按数字排序。
sort -t ":" -n -k2 file.txt
d:1
c:2
b:3
a:4
e:5
f:11

uniq
如果文件中有多行完全相同的内容,希望能删除重复的行,同时还可以统计出完全相同的行出现的总次数, 那么就可以使用uniq命令解决这个问题(但是必须配合sort使用,相邻的才能去重,所以要配合sort)。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
uniq [OPTION]... [INPUT [OUTPUT]]
#选项:-c 计算重复的行

#1.创建一个file.txt文件:
cat >>file2.txt <<EOF
abc
123
abc
123
EOF
#2.uniq需要和sort一起使用, 先使用sort排序, 让重复内容连续在一起才能去重
cat file.txt |sort
123
123
abc
abc
#3.使用uniq去除相邻重复的行
cat file.txt |sort|uniq
123
abc
#4.-c参数能统计出文件中每行内容重复的次数
cat file.txt |sort|uniq -c
2 123
2 abc

wc统计行号

1
2
3
4
5
6
7
wc [OPTION]... [FILE]...
#选项:-l显示文件行数 -c显示文件字节 -w显示文件单词

wc -l /etc/fstab #统计/etc/fstab文件有多少行
wc -l /etc/services #统计/etc/services 文件行号
ls |wc -l #统计当前路径下有多少文件和文件夹
ps aux | grep ssh | wc -l #统计有多少ssh相关的进程

2.10 文件属性

当我们使用ls -l列出目录下所有文件时,通常会以长格的方式显示,其实长格式显示就是我们Windows下看到的文件详细信息,也称为文件属性,那整个文件的属性分为十列。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
-rwxr-xr-x.  1 root root 117656 Jun 30  2016 /bin/ls
srw-rw-rw-. 1 root root 0 Jan 20 10:35 /dev/log
brw-rw----. 1 root disk 8, 0 Jan 20 10:36 /dev/sda
crw--w----. 1 root tty 4, 1 Jan 20 10:36 /dev/tty1
lrwxrwxrwx. 1 root root 22 Jan 13 11:31 /etc/grub2.cfg -> ../boot/grub2/grub.cfg
-rw-r--r--. 1 root root 199 Jan 20 11:03 /etc/hosts
prw-------. 1 root root 0 Jan 20 10:36 /run/dmeventd-client
drwxrwxrwt. 61 root root 8192 Jan 21 13:01 /tmp

############################################
-rw-------. 1:第一个字符是文件类型,其他则是权限
1 2:硬链接次数
root 3:文件属于哪个用户
root 4:文件属于哪个组
1418 5:文件大小
May30 13:58 6,7,8:最新修改的时间与日期
a.cfg 9:文件或目录名称
############################################

文件类型

通常我们使用颜色或者后缀名称来区分文件类型,但很多时候不是很准确,所以我们可以通过ls -l以长格式显示一个文件的属性,通过第一列的第一个字符来近一步的判断文件具体的类型。

  • “-”表示普通文件(文本, 二进制, 压缩, 图片, 日志等)
  • “d”表示目录
  • “l”表示链接文件
  • “p”表示管道文件
  • “b”表示块设备文件,存储设备硬盘 /dev/sda1, /dev/sda2
  • “c”表示字符设备文件,终端 /dev/tty1, /dev/zero
  • “s”表示套接字文件,进程间通信(socket)

但有些情况下,我们无法通过ls -l文件的类型,比如: 一个文件,它可能是普通文件、也可能是压缩文件、或者是命令文件等,那么此时就需要使用file来更加精准的判断这个文件的类型。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
file /etc/hosts
/etc/hosts: ASCII text

file /dev/sda
/dev/sda: block special

file /dev/tty1
/dev/tty1: character special

file /home
/home: directory

file /run/dmeventd-client
/run/dmeventd-client: fifo (named pipe)

权限

其属性可分为三段:[rwx][r-x][r-x],其中第一段表示文件创建者/所有者对该文件所具有的权限,第二段表示创建者/所有者所在的组的其他用户所具有的权限,第三段表示其他组的其他用户所具有的权限。(本人的权限,组内的权限,组外的权限)

  • r(Read,读取权限):对文件而言,具有读取文件内容的权限;对目录来说,具有浏览目录的权限。
  • w(Write,写入权限):对文件而言,具有新增、修改文件内容的权限;对目录来说,具有删除、移动目录内文件的权限。
  • x(Execute,执行权限):对文件而言,具有执行文件的权限;对目录来说,该用户具有进入目录的权限。

软链接/硬链接

文件有文件名与数据,在Linux上被分成两个部分:用户数据 (user data) 与元数据 (metadata)。

  • 用户数据,即文件数据块 (data block),数据块是记录文件真实内容的地方,我们将其称为Block。

  • 元数据,即文件的附加属性,如文件大小、创建时间、所有者等信息,我们称其为Inode。

在Linux中,inode是文件元数据的一部分,但其并不包含文件名,inode号即索引节点号,文件名仅是为了方便人们的记忆和使用,系统或程序通过 inode 号寻找正确的文件数据块。

链接文件

Linux 系统引入了两种链接:硬链接 ( hard link ) 与软链接(soft link)

  • 软链接相当于Windows的快捷方式,软链接文件会将inode指向源文件的block,当我们访问这个软链接文件时,其实访问的是源文件本身。那么当我们对一个文件创建多个软链接,其实就是多个inode指向同一个block。当我们删除软链接文件时,其实只是删除了一个inode指向,并不会对源文件源文件造成影响,但如果删除的是源文件则会造成所有软链接文件失效。

    软链接

  • 若一个inode号对应多个文件名,则称这些文件为硬链接。换言之,硬链接就是同一个文件使用了多个别名,如下图hard link 就是 file 的一个别名,他们有共同的 inode。

硬链接

1
2
3
4
5
6
7
8
# 举例
touch /root/file
ln -s /root/file /tmp/file_bak # root下file链接到/tmp下并重命名为file_bak -s参数:软链接
# 软链接目录
mkdir /soft/nginx1.1 -p
ln -s /soft/nginx1.1/ /soft/nginx # soft下的nginx1.1/文件夹软链接到/soft/nginx
# 硬链接
ln /root/file /tmp/file_hard # 创建硬链接

所有者,组

表示该文件的所有者/创建者(owner)及其所在的组(group)。

文件大小

如果是文件,则表示该文件的大小,单位为字节。
如果是目录,则表示该目录符所占的大小,并不表示该目录下所有文件的大小。

修改日期

该文件最后创建/修改的日期时间。

文件名称

在大多数的linux shell窗口中,还能用颜色来区分不同文件的属性。

  • 灰白色表示普通文件
  • 亮绿色表示可执行文件
  • 亮红色表示压缩文件
  • 灰蓝色表示目录
  • 亮蓝色表示链接文件
  • 亮黄色表示设备文件

总结

四、文件权限管理

在之前的介绍中,我们知道文件的权限属性,下面就来详细介绍linux的权限管理。

1 为什么要引入权限

如果你使用windows系统,你会发现winodws系统也有权限的概念,右键一个文件,点击属性,安全,可以看到如下内容。

image-20211120151452611

这里的完全控制/修改/读取和执行/读取/写入就是权限类别,windows系统为管理员用户分配了这些权限,同理你也可以对这些权限进行更改,比如把文件设置为只读。

操作系统引入权限的原因,首先因为系统是多用户的,也就是说这台机器会给很多人使用,为了保护每个登陆用户的隐私和工作环境不被其他用户干扰,就需要权限系统。(毕竟谁也不愿意自己安装的软件、写的文章被其他人随随便便删掉。)

2 linux的权限概念

在Linux系统中,针对文件定义了三种身份,分别是属主(owner)、属组(group)、其他人(others),每一种身份又对应三种权限,分别是可读(readable)、可写(writable)、可执行(excutable),分别简写为”rwx”。

平时也会看到一些文章写的权限”700”,权限”755”,这其实也是权限的表示方法,用数字和字母对应:

字母 含义 对应权限
r 读取权限 4
w 写入权限 2
x 执行权限 1
- 没有权限 0

权限分为三部分,每个部分都是三个字母表示,也可以通过4、2、1的相加组合得到这些权限,举个例子

字母 含义 对应权限
rw- 读、写 6(4+2+0)
r– 只读 4(4+0+0)
rwx 读、写、执行 7(4+2+1)
没有权限 0(0+0+0)

3 设置权限

使用命令设置权限,比如

1
chmod 755 filename

755rwxr-xr-x,使用数字设置权限非常简便。

另外,在Linux中权限对文件和对目录的影响是有不同区别的。

权限 对文件的影响 对目录的影响
读取权限(r) 具有读取阅读文件内容权限。 具有浏览目录及子目录权限
写入权限(w) 具有新增、修改文件内容的权限 具有增加和删除目录内文件权限
执行权限(x) 具有执行文件的权限 具有进入目录的内容的权限(取决于目录中文件权限)

再具体一点,对于文件的权限,主要都是针对“文件内容”而言的。

  • 读(r):可以读取文件的内容。

  • 写(w):可以编辑,修改文件内容。(但不能删除文件)

  • 执行(x):文件可以被系统执行。

目录的权限,是针对目录里的“文件”而言的。

  • 读(r):表示具有读取目录结构列表的权限,你可以查询该目录下的文件名数据,可以利用ls命令将该目录的内容列表显示出来。

  • 写(w):表示你具有更改目录结构列表的权限,包括以下权限:

    • 新建文件和目录
    • 删除已存在的文件和目录
    • 重命名已存在的文件和目录
    • 转移该目录下的文件和目录
  • 执行(x):表示用户可以进入(cd)该目录作为工作目录。

4 更改属组和属组

使用chown、chgrp命令实现。chown可以更改属主和属组,但是chgrp只能更改属组,所以记住chown就可以。

1
2
3
4
5
6
7
8
9
10
11
12
13
#chown 更改属主以及属组 -R:递归修改

#准备环境,创建文件和目录
mkdir dir/test1 && touch dir/file

#示例1: 修改所属主为bin
chown bin dir/

#示例2: 修改所属组为adm
chown .adm dir/

#示例3: 递归修改目录及目录下的所有文件属主和属组
chown -R root.root dir/

五、文件编辑

1 介绍

因为Linux系统一切皆为文件,而我们工作最多的就是修改某个服务的配置(其实就是修改文件内容)。vi和vim是Linux下的一个文本编辑工具,和winodws的记事本是一样的作用。

1.1 vi和vim有什么区别

vi和vim都是文本编辑器,只不过vim是vi的增强版,可以当作vi的升级版本,vim可以用多种颜色的方式来显示一些特殊的信息。vim里面加入了很多额外的功能,例如支持正则表达式的搜索、多文件编辑、块复制等等。 这对于我们在Linux上进行一些配置文件的修改工作时是很棒的功能。使用vi还是vim取决于个人习惯。

如果你是最小化安装CentOS系统,默认情况下没有vim命令,可以使用yum install vim -y安装

1.2 vim的模式

在使用VIM之前,我们需要先介绍下VIM的三种模式: 普通模式、编辑模式、命令模式,每种模式分别支持多种不同的快捷键,要想高效率地操作文本,就必须先搞清这三种模式的操作区别以及模式之间的切换方法。

  • 普通模式:主要是控制光标移动,可对文本进行复制、粘贴、删除等工作。
  • 编辑模式:主要进行文本内容编辑和修改
  • 命令模式: 主要用于保存或退出文本。

当使用vim命令打开一个文件时,默认处于普通模式;从普通模式切换至编辑模式需要使用按键a/i/o;编辑模式修改完毕后需要先使用ECS返回普通模式;在普通模式输入:/进入命令模式,可实现文件的保存与退出。

2 vim的使用

2.1 普通模式

光标跳转

1
2
3
4
5
6
shift+g		# 光标跳转到尾部
gg # 光标跳转到头部
Ngg # 光标跳转至当前文件内的N行
$ # 光标跳转至当前光标所在行的尾部(正则)
^或者0 # 光标跳转至当前光标所在行的首部(正则)
# 另外在xshell等一些软件上,光标跳转到所在行的首部和尾部可以使用Home和End

对于文件内容很多的时候需要上下翻页

1
2
3
ctrl+f  # 向下翻页
ctrl+b # 向上翻页
# 另外在xshell等一些软件上,翻页也可以使用PageUp和PageDown

复制和粘贴

1
2
3
4
yy       # 复制当前光标所在的行
Nyy # 复制当前光标以及光标向下N行,比如 3yy复制三行
p(小写) # 粘贴至当前光标下一行
P(大写) # 粘贴至当前光标上一行

删除、剪贴、撤销

1
2
3
4
5
6
7
8
dd      # 删除当前光标所在的行(是剪切)
4dd # 删除当前光标所在的行以及往下的3行
dG # 删除当前光标以后的所有行
D # 删除当前光标及光标以后的这一行内容
x # 删除当前光标后的一个字符
X # 删除当前光标前的一个字符
dd & p # 剪切dd,用p粘贴
u # 撤销上一次的操作

替换

1
2
r       # 替换当前光标标记的单个字符
R # 进入REPLACE模式, 连续替换,ESC结束

2.2 编辑模式

1
2
3
4
5
6
7
i   # 进入编辑模式,光标不做任何操作
a # 进入编辑模式,将当前光标往后一位
o # 进入编辑模式,并在当前光标下添加一行空白内容
I # 进入编辑模式,并且光标会跳转至本行的头部
A # 进入编辑模式,将光标移动至本行的尾部
O # 进入编辑模式,并在当前光标上添加一行空白内容
ESC # 退出编辑模式使用ESC

2.3 命令模式

:进入命令模式。

文件保存与退出

1
2
3
4
5
6
7
8
9
10
11
:w        # 保存当前状态
:w! # 强制保存当前状态
:q # 退出当前文档(文档必须保存才能退出)
:q! # 强制退出文档不会修改当前内容
:wq # 先保存,在退出
:wq! # 强制保存并退出
:x # 先保存,在退出
ZZ # 保存退出, shfit+zz
:number # 跳转至对应的行号
:set nu # 显示行号
:set nonu # 不显示行号

文件内容查找

1
2
3
/string # 需要搜索的内容(查找),比如搜索 /bob 搜索bob
n # 按搜索到的内容依次往下进行查找
N # 按搜索到的内容依次往上进行查找

文件内容另存

1
:w /root/test.txt  # 将所有内容另存为/root/test.txt文件中

文件内容读入

1
2
:r  /etc/hosts  # 读入/etc/hosts文件至当前光标下面
:5r /etc/hosts # 指定插入/etc/hosts文件至当前文件的第五行下面

六、用户管理

1 介绍

linux支持多用户,并且Linux系统允许同一时刻多个用户同时登陆,登陆后相互之间操作并不影响。

由于root权限过大,很容易误操作造成系统风险,所以需要新建一些用户,使用普通用户管理服务器。同时,用户还有属组的概念,可以给用户分配到不同的组,使其拥有不同的权限。一个用户可以拥有多个组。

1.1 查看用户信息

1
2
3
id    # 查看当前登录的用户信息
# uid=0(root) gid=0(root) groups=0(root) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
# uid:用户id,gid:组id,groups:用户属于哪些组,context环境信息

1.2 用户存放位置

Linux系统会将用户的信息存放在/etc/passwd,记录了用户的信息,但没有密码信息,密码被存放在/etc/shadow中。也就是说这两个文件非常的重要,不要轻易删除与修改。

1
2
3
4
cat /etc/passwd
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin # nologin不能登录
daemon:x:2:2:daemon:/sbin:/sbin/nologin

passwd详细

1
2
cat /etc/shadow
bin:*:18353:0:99999:7:::

shadow详细

tips:查看系统的所有用户
1
cat /etc/passwd | grep bash

1.3 系统对用户uid的一个约定用法

用户UID 系统中约定的含义
0 超级管理员,最高权限,有着极强的破坏能力
1~200 系统用户,用来运行系统自带的进程,默认已创建
201~999 系统用户,用来运行用户安装的程序,所以此类用户无需登录系统
1000+ 普通用户,正常可以登陆系统的用户,权限比较小,能执行的任务有限

2 用户的CURD

2.1 新增

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
useradd bob		# adduser实际上是软链接到useradd
tail -1 /etc/passwd
# bob:x:1000:1000::/home/bob:/bin/bash

# 选项
# -u 指定要创建用户的UID,不允许冲突
# -g 指定要创建用户默认组
# -G 指定要创建用户附加组,逗号隔开可添加多个附加组
# -d 指定要创建用户家目录
# -s 指定要创建用户的bash shell /bin/bash /sbin/nologin
# -c 指定要创建用户注释信息
# -M 给创建的用户不创建家目录
# -r 创建系统账户,默认无家目录

#1.创建bgx用户,UID5001,基本组students,附加组sa 注释信息:2019 new student,登陆shell:/bin/bash
groupadd sa # 创建组
groupadd students # 创建组
useradd -u 5001 -g students -G sa -c "2019 new student" -s /bin/bash bgx

#2.创建mysql系统用户,-M不建立用户家目录 -s指定nologin使其用户无法登陆系统,创建一个用户只负责运行某个服务
useradd mysql -M -s /sbin/nologin
useradd -r dba -s /sbin/nologin

2.2 修改

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
usermod
# 选项
# -u 指定要修改用户的UID
# -g 指定要修改用户基本组
# -G 指定要修改用户附加组,使用逗号隔开多个附加组, 覆盖原有的附加组,-aG追加
# -d 指定要修改用户家目录 -md 旧家搬新家
# -s 指定要修改用户的bash shell
# -c 指定要修改用户注释信息
# -l 指定要修改用户的登陆名
# -L 指定要锁定的用户
# -U 指定要解锁的用户

# 修改bgx用户uid、gid,附加组 -a表示追加
groupadd -g 5008 network_sa
groupadd -g 5009 devops
usermod -u 6001 -g5008 -a -G 5009 bgx

2.3 删除

1
2
3
4
5
6
7
8
9
userdel
# 选项 -r 删除用户同时删除它的家目录

#1.删除user1用户,但不删除用户家目录和 mail spool
userdel user1
ls /var/spool/mail/

#2.-r参数可以连同用户家目录一起删除(慎用)
userdel -r user1

当我们想删除某个用户的时候,出现user xxx is currently used by process xxx,可能的原因是你创建用户user1之后,使用su命令切换到user1用户下,之后又想删除user1用户,使用su root切换到root用户下,使用userdel user1。出现上述情况的根本原因在于切换回root用户之后,user1还被某个进程占用。

解决方案:ctrl+d(退出当前用户)

2.4 密码修改

创建用户之后,如需要使用该用户登陆系统则需要为用户设定密码,设定密码使用passwd命令。建议密码复杂度一些,不要出现生日、人名等等。

  • 普通用户只允许变更自己的密码,无法修改其他人密码,并且密码长度必须8位字符
  • 管理员用户允许修改任何人的密码,无论密码长度多长或多短
1
2
3
4
# 使用passwd命令修改用户密码
passwd # 给当前用户修改密码
passwd root # 给root用户修改密码
passwd bob # 给bob修改密码,普通用户只能修改自己的密码

3 用户组

3.1 新增组

1
2
#新增组
groupadd group1

3.2 修改组

1
2
3
4
5
# 选项 -g:修改组gid
groupmod -g 1111 group1

# 选项 -n:修改组名(把group1名字改为active_group)
groupmod group1 -n active_group

3.3 删除组

删除时需要注意,如果用户存在基本组则无法直接删除该组,如果删除用户则会移除默认的私有组,而不会移除基本组。

1
2
3
4
5
6
7
# 删除组
groupdel active_group

# 无法删除用户基本组
groupdel network_sa
groupdel: cannot remove the primary group of user 'bgx_bob'
#只有删除用户或者用户变更基本后,方可删除该组

4 提权

生产环境中一般都是禁止root用户直接登录操作系统,通常使用的都是普通用户,当我们使用普通用户执行/sbin目录下的命令时没有权限运行,这种情况下我们无法正常的管理服务器,那如何才能不使用root用户直接登录系统,同时又保证普通用户能完成日常工作?

我们可以使用如下两种方式: su、sudo

  • su:切换用户,使用普通用户登录,然后使用su命令切换到root。优点:简单;缺点:需要知道root密码
  • sudo:提权,当需要使用root权限时进行提权,而无需切换至root用户,优点:安全;缺点:复杂

4.1 su

普通用户使用su -可以直接切换至root用户,但需要输入root用户的密码。
root用户使用su - username切换普通用户不需要输入密码。

1
2
su bob	# 表示不打开新的bash窗口,登录在当前目录,不加载环境变量
su - bob # 打开新的bash窗口,登录在bob的家目录,加载环境变量

4.2 sudo

su命令在切换root用户时,都需要输入root密码,这样系统会变得非常不安全。sudo是linux系统管理指令,是允许系统管理员让普通用户执行一些或者全部的root命令的一个工具。sudo使一般用户不需要知道超级用户的密码即可获得权限。

首先超级用户将普通用户的名字、可以执行的特定命令、按照哪种用户或用户组的身份执行等信息,登记在特殊的文件中,在一般用户需要取得特殊权限时,其可在命令前加上sudo,此时sudo将会询问该用户自己的密码,回答后系统即会将该命令的进程以超级用户的权限运行。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# 1.快速配置sudo方式
[root@localhost ~]# usermod mike -G wheel # 把mike加到wheel组中

# 2.切换到mike用户
[root@localhost ~]# su - mike

#2.检查普通用户能提权的命令
[mike@localhost ~]$ sudo -l
User mike may run the following commands on this host:
(ALL) ALL
用户 mike 可以在 localhost 上运行以下命令:
(ALL) ALL

#3.普通用户无法在media下创建文件
[mike@localhost home]$ cd /media/
[mike@localhost media]$ touch a.txt
touch: 无法创建"a.txt": 权限不够

#4.使用sudo提权,需要输入mike自己的密码
[mike@localhost media]$ sudo touch a.txt
[mike@localhost media]$ ls
a.txt

这样做的缺点是提升的权限太大,有时只需要给普通用户几个权限就够了。前面提到过超级用户首先将授权信息登记在特殊的文件中,这个文件一般是/etc/sudoers,可以在这里配置。下面是该文件的内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
## Sudoers allows particular users to run various commands as
## the root user, without needing the root password.
## 该文件允许特定用户像root用户一样使用各种各样的命令,而不需要root用户的密码
## Examples are provided at the bottom of the file for collections
## of related commands, which can then be delegated out to particular
## users or groups.
## 在文件的底部提供了很多相关命令的示例以供选择,这些示例都可以被特定用户或用户组所使用
## This file must be edited with the 'visudo' command.
## 该文件必须使用"visudo"命令编辑

## Host Aliases
## 主机别名
## Groups of machines. You may prefer to use hostnames (perhaps using
## wildcards for entire domains) or IP addresses instead.
## 对于一组服务器,你可能会更喜欢使用主机名(可能是全域名的通配符)
## 或IP地址代替,这时可以配置主机别名
# Host_Alias FILESERVERS = fs1, fs2
# Host_Alias MAILSERVERS = smtp, smtp2

## User Aliases
## 用户别名
## These aren't often necessary, as you can use regular groups
## (ie, from files, LDAP, NIS, etc) in this file - just use %groupname
## rather than USERALIAS
## 这并不很常用,因为你可以通过使用组来代替一组用户的别名
# User_Alias ADMINS = jsmith, mikem


## Command Aliases
## These are groups of related commands...
## 指定一系列相互关联的命令(当然可以是一个)的别名,通过赋予该别名sudo权限,
## 可以通过sudo调用所有别名包含的命令,下面是一些示例

## Networking
## 网络操作相关命令别名
# Cmnd_Alias NETWORKING = /sbin/route, /sbin/ifconfig, /bin/ping, /sbin/dhclient, /usr/bin/net, /sbin/iptables, /usr/bin/rfcomm, /usr/bin/wvdial, /sbin/iwconfig, /sbin/mii-tool

## Installation and management of software
## 软件安装管理相关命令别名
# Cmnd_Alias SOFTWARE = /bin/rpm, /usr/bin/up2date, /usr/bin/yum

## Services
## 服务相关命令别名
# Cmnd_Alias SERVICES = /sbin/service, /sbin/chkconfig, /usr/bin/systemctl start, /usr/bin/systemctl stop, /usr/bin/systemctl reload, /usr/bin/systemctl restart, /usr/bin/systemctl status, /usr/bin/systemctl enable, /usr/bin/systemctl disable

## Updating the locate database
## 本地数据库升级命令别名
# Cmnd_Alias LOCATE = /usr/bin/updatedb

## Storage
## 磁盘操作相关命令别名
# Cmnd_Alias STORAGE = /sbin/fdisk, /sbin/sfdisk, /sbin/parted, /sbin/partprobe, /bin/mount, /bin/umount

## Delegating permissions
## 代理权限相关命令别名
# Cmnd_Alias DELEGATING = /usr/sbin/visudo, /bin/chown, /bin/chmod, /bin/chgrp

## Processes
## 进程相关命令别名
# Cmnd_Alias PROCESSES = /bin/nice, /bin/kill, /usr/bin/kill, /usr/bin/killall

## Drivers
## 驱动命令别名
# Cmnd_Alias DRIVERS = /sbin/modprobe

# Defaults specification
# 环境变量的相关配置

#
# Refuse to run if unable to disable echo on the tty.
#
Defaults !visiblepw

#
# Preserving HOME has security implications since many programs
# use it when searching for configuration files. Note that HOME
# is already set when the the env_reset option is enabled, so
# this option is only effective for configurations where either
# env_reset is disabled or HOME is present in the env_keep list.
#
Defaults always_set_home
Defaults match_group_by_gid

# Prior to version 1.8.15, groups listed in sudoers that were not
# found in the system group database were passed to the group
# plugin, if any. Starting with 1.8.15, only groups of the form
# %:group are resolved via the group plugin by default.
# We enable always_query_group_plugin to restore old behavior.
# Disable this option for new behavior.
Defaults always_query_group_plugin

Defaults env_reset
Defaults env_keep = "COLORS DISPLAY HOSTNAME HISTSIZE KDEDIR LS_COLORS"
Defaults env_keep += "MAIL PS1 PS2 QTDIR USERNAME LANG LC_ADDRESS LC_CTYPE"
Defaults env_keep += "LC_COLLATE LC_IDENTIFICATION LC_MEASUREMENT LC_MESSAGES"
Defaults env_keep += "LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER LC_TELEPHONE"
Defaults env_keep += "LC_TIME LC_ALL LANGUAGE LINGUAS _XKB_CHARSET XAUTHORITY"

#
# Adding HOME to env_keep may enable a user to run unrestricted
# commands via sudo.
#
# Defaults env_keep += "HOME"

Defaults secure_path = /sbin:/bin:/usr/sbin:/usr/bin

## Next comes the main part: which users can run what software on
## which machines (the sudoers file can be shared between multiple
## systems).
## 下面是主要部分:什么用户在什么机器上上可以执行什么命令(sudoers文件可以在多个机器上共享)
## Syntax:
## 语法:
##
## user MACHINE=COMMANDS
## 用户 登录的主机=可以使用sudo执行的命令
##
## The COMMANDS section may have other options added to it.
## 命令部分可以附带一些其它的选项
##
## Allow root to run any commands anywhere
## 允许root用户在任意主机下执行任意命令
root ALL=(ALL) ALL

## Allows members of the 'sys' group to run networking, software,
## service management apps and more.
# %sys ALL = NETWORKING, SOFTWARE, SERVICES, STORAGE, DELEGATING, PROCESSES, LOCATE, DRIVERS
## 允许sys中户组中的用户使用NETWORKING等所有别名中配置的命令

## Allows people in group wheel to run all commands
## 允许wheel用户组中的用户在任意位置执行所有命令
%wheel ALL=(ALL) ALL

## Same thing without a password
## 允许wheel用户组中的用户在不输入该用户的密码的情况下使用所有命令
# %wheel ALL=(ALL) NOPASSWD: ALL

## Allows members of the users group to mount and unmount the
## cdrom as root
## 允许users用户组中的用户像root用户一样使用mount、unmount、chrom命令
# %users ALL=/sbin/mount /mnt/cdrom, /sbin/umount /mnt/cdrom

## Allows members of the users group to shutdown this system
## 允许users用户组中的用户像root用户一样使用shutdown命令
# %users localhost=/sbin/shutdown -h now

## Read drop-in files from /etc/sudoers.d (the # here does not mean a comment)
#includedir /etc/sudoers.d

这个文件很长,但主要的部分很简单,我们只需要按照范例进行修改即可。但是并不推荐直接修改这个文件,而是使用visudo命令编辑。你只需要copy一行,然后把“root”改成你想要添加的那个用户名就可以了。使用visudo的好处就是它会帮你自动进行语法检查,加锁防止两个管理员同时修改这个文件。所以,强烈建议使用visudo

第一种方式:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 1.使用sudo定义分组,这个系统group没什么关系
User_Alias OPS = ldd,zqs,xhl
User_Alias DEV = bob,mike

# 2.定义可执行的命令组,便于后续调用
Cmnd_Alias NETWORKING = /sbin/ifconfig, /bin/ping
Cmnd_Alias SOFTWARE = /bin/rpm, /usr/bin/yum
Cmnd_Alias SERVICES = /sbin/service, /usr/bin/systemctl start
Cmnd_Alias STORAGE = /bin/mount, /bin/umount
Cmnd_Alias DELEGATING = /bin/chown, /bin/chmod, /bin/chgrp
Cmnd_Alias PROCESSES = /bin/nice, /bin/kill, /usr/bin/kill, /usr/bin/killall

# 3.使用sudo开始分配权限,用于分配OPS组的人可以执行什么,DEV组的人可以执行什么
OPS ALL=(ALL) NETWORKING,SOFTWARE,SERVICES,STORAGE,DELEGATING,PROCESSES
DEV ALL=(ALL) SOFTWARE,PROCESSES

第二种方式:使用groupadd添加组,然后给组分配sudo的权限,如果有新用户加入,直接将用户添加到该组。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#1.添加两个真实的系统组,  group_dev group_op
groupadd group_dev
groupadd group_op

#2.添加两个用户,group_dev(user_a user_b) group_op(user_c user_d)
useradd user_a -G group_dev
useradd user_b -G group_dev
useradd user_c -G group_op
useradd user_d -G group_op

#3.添加密码
echo "1" | passwd --stdin user_a
echo "1" | passwd --stdin user_b
echo "1" | passwd --stdin user_c
echo "1" | passwd --stdin user_d

#4.在sudo中配置规则
[root@localhost ~]# visudo
Cmnd_Alias NETWORKING = /sbin/ifconfig, /bin/ping
Cmnd_Alias SOFTWARE = /bin/rpm, /usr/bin/yum
Cmnd_Alias SERVICES = /sbin/service, /usr/bin/systemctl start
Cmnd_Alias STORAGE = /bin/mount, /bin/umount
Cmnd_Alias DELEGATING = /bin/chown, /bin/chmod, /bin/chgrp
Cmnd_Alias PROCESSES = /bin/nice, /bin/kill, /usr/bin/kill, /usr/bin/killall

%group_dev ALL=(ALL) SOFTWARE
%group_op ALL=(ALL) SOFTWARE,PROCESSES

#5.检查sudo是否配置有错
[root@localhost ~]# visudo -c
/etc/sudoers: parsed OK

最后了解一下sudo的执行过程

sudo执行过程

七、压缩和解压

在linux安装一些软件时,可能需要下载压缩包安装,所以解压是非常重要的操作。你可能会使用一些ftp工具将windows的压缩包上传到linux上,首先要知道,windows常用的压缩格式有rarzip,在linux上常用的是tar.gzzip,Linux上的压缩格式放在windows系统下都是可以正常打开的。但是windows上的rar格式在linux上不支持(需要安装插件),所以互相传输文件一般采用zip

1 zip

使用zip可以对文件进行压缩打包,解压使用unzip命令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# 默认情况下没有zip和unzip工具,需要进行安装
yum install zip unzip -y

# 1.压缩文件为zip包
# zip 压缩表名 压缩的文件
zip filename.zip filename
# 打包不同目录下的不同文件
zip filename1.zip file1 file2 /etc/hosts

# 2.压缩目录为zip包 (-r:递归,压缩文件夹)
zip -r dir.zip dir/

# 3.查看zip压缩包是否是完整的
zip -T filename.zip

# 4.不解压,查看压缩包中的内容
unzip -l filename.zip
unzip -t filename.zip

# 5.解压zip文件包, 默认解压至当前目录
unzip filename.zip

# 6.解压zip内容至/opt目录
unzip filename.zip -d /opt/

2 tar

tar是linux下最常用的压缩与解压缩,支持文件和目录的压缩归档。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#语法:tar [-zjxcvfpP] filename 
c #创建新的归档文件
x #对归档文件解包
t #列出归档文件里的文件列表
v #输出命令的归档或解包的过程
f #指定包文件名,多参数f写最后

z #使用gzip压缩归档后的文件(.tar.gz)
j #使用bzip2压缩归档后的文件(.tar.bz2)
J #使用xz压缩归档后的文件(tar.xz)
C #指定解压目录位置
X #排除多个文件(写入需要排除的文件名称)
h #打包软链接
--hard-dereference #打包硬链接
--exclude #在打包的时候写入需要排除文件或目录


#常用打包与压缩组合
czf #打包tar.gz格式 常用****
cjf #打包tar.bz格式
cJf #打包tar.xz格式

zxf #解压tar.gz格式
jxf #解压tar.bz格式
xf #自动选择解压模式
xvf #显示解压过程
tf #查看压缩包内容

# 最常用的
tar -czf filename # 压缩
tar -zxf filename # 解压

# 举例
tar czf file.tar.gz a b c # 把a,b,c文件打包成file.tar.gz
tar xzf file.tar.gz # 在当前目录解压file.tar.gz
tar xzf file.tar.gz -C /tmp# 解压file.tar.gz至指定的/tmp目录

3 gzip打包与压缩

关于gzip,它只可以压缩文件,对文件夹无效。而且压缩后删除原文件,解压后删除压缩包。这个特性使得它很鸡肋。

安装gzip:

1
yum install gzip -y

示例:

1
2
3
gzip file       #对文件进行压缩
zcat file.gz #查看gz压缩后的文件
gzip -d file.gz #解压gzip的压缩包

虽然看起来没用,但是有一个使用场景:当需要让某个配置文件不生效时,可以利用gzip的特性,快速关闭和启用配置文件。在下面的软件管理中会具体提到。

八、软件管理

1 RPM介绍

RPM是Red-Hat Package Manager(红帽软件包管理器)的缩写,一种用于互联网下载包的打包及安装工具,它包含在某些Linux分发版中。它生成具有.rpm扩展名的文件。

如下图,是一个rpm包,它由这几个部分组成:软件名称,版本号,发布次数,平台,扩展名。

版本号4.2.46中,4代表大版本号,2代表小版本号,46是修正次数,每次发布都会自增。

x86_64代表64位架构。

img

2 使用RMP包安装升级卸载

RPM包是已经编译打包的文件,安装起来也不难,简单的一个命令即可安装。

如果你使用虚拟机,那么你可以挂载操作系统镜像,然后执行:

1
mount /dev/cdrom /mnt

mnt路径下的Packages内就是系统镜像自带的一些rpm包。

以下列出了rpm命令进行安装软件的常用参数。

选项 描述
-i 安装rpm
-v 显示安装详细信息
-h 显示安装rpm进度
–force 强制重新安装
–nodeps 忽略依赖关系

安装本地软件包,需要指定软件包绝对路径。(软件包在当前目录不需要绝对路径)

1
2
rpm -ivh /mnt/Packages/tree-1.6.0-10.el7.x86_64.rpm
rpm -ivh /mnt/Packages/vsftpd-3.0.2-22.el7.x86_64.rpm

如果软件包存在, 强制再次安装

1
rpm -ivh --force /mnt/Packages/tree-1.5.3-3.el6.x86_64.rpm

rpm安装某些包时,会出现安装不上的问题,原因是rpm包之间有依赖关系。使用nodeps可以忽略依赖关系安装:

1
rpm -ivh --nodeps  /mnt/Packages/tree-1.6.0-10.el7.x86_64.rpm

以上都是本地挂载镜像安装。rpm还可以联网安装,指定一个远程地址即可 。

1
2
3
4
# 远程url安装
rpm -ivh https://mirrors.aliyun.com/zabbix/zabbix/3.0/rhel/7/x86_64/zabbix-agent-3.0.9-1.el7.x86_64.rpm
# 升级用U
rpm -Uvh https://mirrors.aliyun.com/zabbix/zabbix/4.2/rhel/7/x86_64/zabbix-agent-4.2.8-1.el7.x86_64.rpm

卸载rpm包使用-e选项,注意卸载时需要先把依赖的包卸载掉,如果依赖的包是系统所必须的,那就不能卸载这个包。

1
2
3
4
# 卸载zabbix-agent
rpm -e zabbix-agent
# 查询zabbix-agent
rpm -q zabbix-agent

3 查询已安装的rpm包

下面列出了查询常用的选项:

选项 描述
rpm -q 查看指定软件包是否安装(常用)
rpm -qa 查看系统中已安装的所有RPM软件包列表
rpm -qi 查看指定软件的详细信息
rpm -ql 查询指定软件包所安装的目录、文件列表(常用)
rpm -qc 查询指定软件包的配置文件(只有etc下的配置文件)
rpm -qf 查询文件或目录属于哪个RPM软件
rpm -qip 查询未安装的rpm包详细信息
rpm -qlp 查询未安装的软件包会产生哪些文件

举例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#查询vsftpd这个rpm包是否安装
rpm -q vsftpd

#模糊查找系统已安装的rpm包
rpm -qa |grep ftp

#查询vsftpd软件包的相关信息
rpm -qi vsftpd

#查询rpm包所安装的文件
rpm -ql vsftpd

#查询rpm包相关的配置文件
rpm -qc vsftpd

#查询配置文件或命令来自于哪个rpm包(只能查已经安装过的)
rpm -qf /etc/vsftpd/vsftpd.conf # 查看这个配置文件是
rpm -qf /usr/sbin/vsftpd
rpm -qf /usr/sbin/ifconfig
# 想看未安装的
yum provides vim

#查询未安装的软件包会产生哪些文件
rpm -qlp /mnt/Packages/samba-3.6.23-41.el6.x86_64.rpm

#查询未安装的软件包会产生哪些文件
rpm -qip /mnt/Packages/samba-3.6.23-41.el6.x86_64.rpm

4 yum介绍

介绍完rpm,你会发现它有一个缺点,那就是无法处理依赖。有依赖就不能安装和卸载,非常麻烦。

yum解决了该问题。Yum是RedHat以及CentOS中的软件包管理器,能够通过互联网下载.rpm包并且安装,并可以自动处理依赖性关系,无须繁琐地一次次下载、安装。这里有一个yum源的概念:要使用yum工具安装更新软件或系统,就需要有一个包含各种rpm软件包的repository(软件仓库),仓库可以是本地仓库,也可以是网络仓库。这个软件仓库我们习惯称为 yum 源。

要使用yum首先要有源。/etc/yum.repos.d/目录下存放的xxx.repo文件就是yum源。

1
2
yum repolist # 该命令可以查看现在有多少源
yum repolist all # 查看所有源,被禁用的也列出来

5 yum换源

默认情况使用的是官方源(下图是bfsu的镜像源)

如果使用yum安装软件,提示不存在,那么可以考虑换源。换成阿里开源镜像站的yum源:

实际上就是下载阿里的CentOS-Base.repo /etc/yum.repos.d/,比如centOS7的基本源

1
wget -O /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-7.repo

image-20211120003041908

另外还有扩展源,为什么要装扩展源,因为有很多软件在基本源中没有。

1
wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo

除了配置阿里yum源之外,学习nginx时可能要使用官方的yum源来安装。

搭配gzip的应用

之前我们提到过gzip有一个使用场景。比如我们现在配置了阿里云的yum扩展源,里面已经有nginx了,但是版本比较旧。想要最新版本的nginx,就只能去官网配置yum源。但是,两个配置会优先使用扩展源,即使配置了官方源可能也不会生效。此时就可以利用gzip的特性,快速关闭和启用配置文件。

1
2
cd /etc/yum.repos.d/
gzip *

我们把所有的yum源全部打包成.gz文件,原文件也被删除,现在yum就没有可用的源了。

然后配置nginx官方源

1
2
vim /etc/yum.repos.d/nginx.repo
# 新建一个文件nginx.repo

复制以下内容粘贴

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
[nginx-stable]
name=nginx stable repo
baseurl=http://nginx.org/packages/centos/$releasever/$basearch/
gpgcheck=1
enabled=1
gpgkey=https://nginx.org/keys/nginx_signing.key
module_hotfixes=true

[nginx-mainline]
name=nginx mainline repo
baseurl=http://nginx.org/packages/mainline/centos/$releasever/$basearch/
gpgcheck=1
enabled=0
gpgkey=https://nginx.org/keys/nginx_signing.key
module_hotfixes=true

现在可以使用yum安装最新版本的nginx

1
yum install nginx

安装完之后,再使用gzip解压

1
gzip -d *

6 源码安装

源码包指的是开发编写好的程序源代码,但并没有将其编译为一个能正常使用的工具。yum安装十分简单,但是有些包可能没有收录,如果yum安装不上可能就需要去软件官网下载源码安装。源码安装还有一个好处,那就是可以获取到最新的包,并且可以自行修改软件源码。

6.1 获取源码包

一般来说软件包都可以在官网下载,比如nginx、mysql、python等等。以安装nginx为例,去官网下载安装包。

1
wget http://nginx.org/download/nginx-1.21.4.tar.gz

6.2 编译安装

解压

1
tar -zxf nginx-1.21.4.tar.gz

进入目录,编译安装

1
2
3
cd nginx-1.21.4
./configure # 并不是所有的安装文件都有configure文件,可以先ls查看
make install prefix=/usr/local/nginx

配置nginx环境变量,并使环境变量生效

1
2
echo 'export PATH=$PATH:/usr/local/nginx/sbin' >> /etc/bashrc
source /etc/bashrc

查看nginx版本号

1
nginx -v

如果出现版本号就说明已经安装完毕了。常用命令如下:

1
2
3
4
5
6
7
# 命令
nginx # 启动服务
nginx -v # 查看版本
nginx -t # 查看nginx的默认配置文件的安装位置
nginx -s reload # 重新加载服务
nginx -s stop # 重启
nginx -s stop # 停止

6.3 报错信息处理

一般报错都是nginx依赖的模块没有安装,对应安装即可。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
checking for C compiler ... not found ./configure: error: C compiler cc is not found 
# yum -y install gcc gcc-c++ make

./configure: error: the HTTP rewrite module requires the PCRE library.
You can either disable the module by using --without-http_rewrite_module
option, or install the PCRE library into the system, or build the PCRE library
statically from the source with nginx by using --with-pcre=<path> option.
# yum install -y pcre-devel

./configure: error: the HTTP gzip module requires the zlib library.
You can either disable the module by using --without-
http_gzip_module option, or install the zlib library into the
system, or build the zlib library statically from the source with
nginx by using --with-zlib=<path> option.
# yum -y install zlib-devel

./configure: error: SSL modules require the OpenSSL library.
You can either do not enable the modules, or install the OpenSSL
library into the system, or build the OpenSSL library statically
from the source with nginx by using --with-openssl=<path> option.
# yum -y install openssl-devel

想要省事,就直接把依赖先安装好。

1
yum install -y gcc gcc-c++ make pcre-devel zlib-devel openssl-devel

总结一下安装流程:

img

7 几种安装方式比较

分类 安装方式 特点
rpm包 命令安装 优点:安装简单;缺点:软件版本偏低,需要手动解决依赖,有些包可能没有收录
yum包 命令安装 优点:安装简单,自动解决依赖;缺点:软件版本偏低,有些包可能没有收录
源码包 手动编译安装 优点:软件版本最新;缺点:安装繁琐

九、系统服务systemd

参考文章:Systemd 入门教程:命令篇

1 系统服务介绍

系统服务是在后台运行的应用程序,并且可以提供一些本地系统或网络的功能。我们把这些应用程序称作服务,也就是Service。它们通常都会监听某个端口,等待其它程序的请求,比如mysql,nginx等等。

linux的启动流程大致分为开机自检BIOS-->MBR启动引导-->硬盘启动-->加载内核-->启动初始化进程。到这一步时,linux内核的一些系统的不同版本使用的初始化进程是不同的。比如CentOS6使用init进程,而CentOS7使用Systemd。

2 systemd介绍

linux一直以来都是采用init进程作为初始进程,但是init有两个缺点:

  • 启动时间长。Init进程是串行启动,只有前一个进程启动完,才会启动下一个进程。
  • 启动脚本复杂,初始化完成后系统会加载很多脚本,脚本都会处理各自的情况,这会让脚本变得很复杂。

Systemd 就是为了解决这些问题而诞生的。它的设计目标是,为系统的启动和管理提供一套完整的解决方案。使用了 Systemd,就不需要再用init了。Systemd 取代了initd,成为系统的第一个进程(PID 等于 1),其他进程都是它的子进程。

相比于init,systemd有以下优点:

  • 最新系统都采用systemd管理(RedHat7,CentOS7,Ubuntu15等)
  • Centos7支持开机并行启动服务,显著提高开机启动效率
  • Centos7关机只关闭正在运行的服务
  • Centos7服务的启动与停止不再使用脚本进行管理
  • 原有service不会关闭程序产生的子进程,Centos7使用systemd解决原有模式缺陷

systemd架构图:

img

3 systemd配置文件

3.1 概述

Systemd可以管理所有系统资源。不同的资源统称为 Unit(单位)。每一个 Unit 都有一个配置文件,告诉 Systemd 怎么启动这个 Unit 。

1
2
3
/usr/lib/systemd/system/ # 目录下是真正的system的配置
/etc/systemd/system/ # 配置文件,大部分是软链接
/etc/systemd/system/multi-user.target.wants/ # 开机启动的程序都在这里配置

Systemd 默认从目录/etc/systemd/system/读取配置文件。但是,里面存放的大部分文件都是符号链接,指向目录/usr/lib/systemd/system/,真正的配置文件存放在这里。我们通过systemctl设置开机启动,其实质是增加由/usr/lib/systemd/system//etc/systemd/system/multi-user.target.wants/下的软链接。

下图展示的就是这些配置文件:

image-20211120202146100

3.2 配置文件的格式

任意打开一个配置文件,你会发现他们的格式有共同点。

1
2
3
4
5
6
7
8
9
[Unit]
Description=ATD daemon

[Service]
Type=forking
ExecStart=/usr/bin/atd

[Install]
WantedBy=multi-user.target

配置文件分成几个区块,每个块之间使用中括号[]区别,注意,配置文件的区块名和字段名,都是大小写敏感的。区块内部是一些键值对,等号两侧不能有空格。

[Unit]区块通常是配置文件的第一个区块,用来定义Unit的元数据,以及配置与其他Unit的关系。它的主要字段如下。

1
2
3
4
5
6
7
8
9
10
Description:简短描述
Documentation:文档地址
Requires:当前 Unit 依赖的其他 Unit,如果它们没有运行,当前 Unit 会启动失败
Wants:与当前 Unit 配合的其他 Unit,如果它们没有运行,当前 Unit 不会启动失败
BindsTo:与Requires类似,它指定的 Unit 如果退出,会导致当前 Unit 停止运行
Before:如果该字段指定的 Unit 也要启动,那么必须在当前 Unit 之后启动
After:如果该字段指定的 Unit 也要启动,那么必须在当前 Unit 之前启动
Conflicts:这里指定的 Unit 不能与当前 Unit 同时运行
Condition...:当前 Unit 运行必须满足的条件,否则不会运行
Assert...:当前 Unit 运行必须满足的条件,否则会报启动失败

[Service]区块用来 Service 的配置,只有 Service 类型的 Unit 才有这个区块。它的主要字段如下。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
Type:定义启动时的进程行为。它有以下几种值。
Type=simple:默认值,执行ExecStart指定的命令,启动主进程
Type=forking:以 fork 方式从父进程创建子进程,创建后父进程会立即退出
Type=oneshot:一次性进程,Systemd 会等当前服务退出,再继续往下执行
Type=dbus:当前服务通过D-Bus启动
Type=notify:当前服务启动完毕,会通知Systemd,再继续往下执行
Type=idle:若有其他任务执行完毕,当前服务才会运行
ExecStart:启动当前服务的命令
ExecStartPre:启动当前服务之前执行的命令
ExecStartPost:启动当前服务之后执行的命令
ExecReload:重启当前服务时执行的命令
ExecStop:停止当前服务时执行的命令
ExecStopPost:停止当其服务之后执行的命令
RestartSec:自动重启当前服务间隔的秒数
Restart:定义何种情况 Systemd 会自动重启当前服务,可能的值包括always(总是重启)、on-success、on-failure、on-abnormal、on-abort、on-watchdog
TimeoutSec:定义 Systemd 停止当前服务之前等待的秒数
Environment:指定环境变量

[Install]通常是配置文件的最后一个区块,用来定义如何启动,以及是否开机启动。它的主要字段如下。

1
2
3
4
WantedBy:它的值是一个或多个 Target,当前 Unit 激活时(enable)符号链接会放入/etc/systemd/system目录下面以 Target 名 + .wants后缀构成的子目录中
RequiredBy:它的值是一个或多个 Target,当前 Unit 激活时,符号链接会放入/etc/systemd/system目录下面以 Target 名 + .required后缀构成的子目录中
Alias:当前 Unit 可用于启动的别名
Also:当前 Unit 激活(enable)时,会被同时激活的其他 Unit

如需查看完整字段,请参阅官方文档,或者中文翻译文档

3.3 举例:nginx的service配置

在我的本地博客部署这篇博客中,有介绍nginx的配置,这里补充一下。

1
2
3
4
5
6
7
8
9
10
11
12
13
[Unit]
Description=nginx
After=network.target

[Service]
Type=forking
ExecStart=/usr/local/nginx/sbin/nginx
ExecReload=/usr/local/nginx/sbin/nginx -s reload
ExecStop=/usr/local/nginx/sbin/nginx -s quit
PrivateTmp= true # PrivateTmp=True表示给服务分配独立的临时空间

[Install]
WantedBy=multi-user.target # 运行级别

这里的运行级别,就是操作系统当前正在运行的功能级别。级别从0到6,如下:

运行级别 systemd目标名称 作用
0 runlevel0.target, poweroff.target 关机
1 runlevel1.target, rescue.target 单用户模式
2 runlevel2.target, multi-user.target 暂未使用
3 runlevel3.target, multi-user.target 多用户的文本界面(黑框)
4 runlevel4.target, multi-user.target 没有使用
5 runlevel5.target, graphical.target 多用户的图形界面
6 runlevel6.target, reboot.target 重启
原理(了解)

/etc/rc.d/init.d下有许多服务器脚本程序,一般称为服务(service),在/etc/rc.d下有7个名为rcN.d的目录,对应系统的7个运行级别。

image-20211120212219508

rcN.d下都是一些软链接文件,这些链接文件都指向/etc/rc.d/init.d目录下的service脚本文件。比如以rc3.d举例

image-20211120212620904

命名规则为K+nn+服务名或S+nn+服务名,其中nn为两位数字。

系统启动时,会根据运行级别进入对应的rcN.d目录,并按照文件名顺序检索目录下的链接文件。对于以K开头的文件,系统将终止对应的服务;对于以S开头的文件,系统将启动对应的服务。

查看系统运行级别可以使用命令:

1
runlevel

一般来说,默认选3就可以。也就是multi-user.target

4 systemctl相关命令

systemctl是Systemd的主命令,用于管理系统。比如管理服务的启动、重启、停止、重载、查看状态等。对于用户来说,最常用的是下面这些命令,用于启动和停止 Unit(主要是 service)。想要使用systemctl命令,必须确保软件的配置文件在/usr/lib/systemd/system/目录下,一般来说yum安装会自动配置,但是二进制安装不会,需要手动配置(去该目录下创建一个xxx.service文件)。另外,一旦修改配置文件,就要让Systemd重新加载配置文件,否则修改不会生效。

systemctl命令 说明
systemctl start crond.service 启动服务;cround为服务名,.service可以不加,下同
systemctl stop crond.service 停止服务
systemctl restart crond.service 重启服务
systemctl kill crond.service 杀死一个服务的所有子进程
systemctl reload crond.service 重新加载配置
systemctl status crond.servre 查看服务运行状态
systemctl is-active sshd.service 查看服务是否在运行中
systemctl mask crond.servre 禁止服务运行
systemctl unmask crond.servre 取消禁止服务运行

当我们使用systemctl启动一个守护进程后,可以通过sytemctl status 进程名查看此守护进程的状态。比如systemctl status nginx.service(可以不写.service),相关状态如下:

状态 描述
loaded 服务单元的配置文件已经被处理
active(running) 服务持续运行
active(exited) 服务成功完成一次的配置
active(waiting) 服务已经运行但在等待某个事件
inactive 服务没有在运行
enabled 服务设定为开机运行
disabled 服务设定为开机不运行
static 服务开机不启动,但可以被其他服务调用启动

systemctl设置服务开机启动、不启动、查看各级别下服务启动状态等常用命令:

systemctl命令(CentOS7) 描述
systemctl enable crond.service 开机自动启动
systemctl disable crond.service 开机不自动启动
systemctl list-unit-files 查看各个级别下服务的相关状态
systemctl is-enabled crond.service 查看特定服务是否为开机自启动
systemctl is-active crond.service 查看特定服务是否为正在运行
systemctl daemon-reload 创建新服务文件;修改了依赖关系,需要重载变更,否则不生效

十、进程管理

程序在运行后,我们需要了解进程的运行状态。查看进程的状态分为: 静态和动态两种方式。

1 使用ps命令查看进程状态

1
2
3
4
ps -aux
# -a:显示当前终端的所有进程信息
# -u:以用户的形式显示进程信息
# -x:显示后台进程运行的参数

image-20211120230548993

状态 描述
USER 启动进程的用户
PID 进程运行的ID号
%CPU 进程占用CPU百分比
%MEM 进程占用内存百分比
VSZ 进程占用虚拟内存大小 (单位KB)
RSS 进程占用物理内存实际大小 (单位KB)
TTY 进程是由哪个终端运行启动的tty1、pts/0等。?表示内核程序与终端无关(远程连接会通过tty打开一个bash:tty)
STAT 进程运行过程中的状态 man ps (/STATE)
START 进程的启动时间
TIME 进程占用 CPU 的总时间(为0表示还没超过秒)
COMMAND 程序的运行指令,[ 中括号 ] 属于内核态的进程。 没有 [ ] 的是用户态进程。

选项-aux看不到父进程,我们使用-ef选项查看

1
2
3
ps -ef
# -e 显示所有进程
# -f 全格式。

image-20211120231413533

状态 描述
UID 用户ID
PID 进程ID
PPID 父进程ID
C CPU用于计算执行优先级的因子。数值越大,表明进程是CPU密集型运算, 执行优先级会降低;数值越小,表明进程是I/O密集型运算,执行优先级会提高
STIME 进程启动的时间
TTY 完整的终端名称
TIME 进程占用 CPU 的总时间(为0表示还没超过秒)
CMD 程序的运行指令,[ 中括号 ] 属于内核态的进程。 没有 [ ] 的是用户态进程。

过滤某些进程

1
ps aux | grep bash # 过滤bash

2 使用top命令查看进程状态

top命令提供系统进程的动态的实时情况

1
top

image-20211120232352113

状态 描述
Tasks: 103 total 当前进程的总数
1 running 正在运行的进程数
102 sleeping 睡眠的进程数
0 stopped 停止的进程数
0 zombie 僵尸进程数
%Cpu(s) 平均cpu使用率,按1查看每个cpu具体状态
0.0 us 用户进程占用cpu百分比
0.2 sy 内核进程占用百分比
0.0 ni 优先级进程占用cpu的百分比
99.8 id 空闲cpu
0.0 wa CPU等待IO完成的时间,大量的io等待,会变高
0.0 hi 硬中断,占的CPU百分比
0.0 si 软中断,占的CPU百分比
0.0 st 虚拟机占用物理CPU的时间

top是一个强大的工具,在top界面,你可以使用这些常用按键

字母 含义
h 查看帮助
1 数字1,显示所有CPU核心的负载
z 以高亮显示数据
b 高亮显示处于R(进行中)状态的进程
M 按内存使用百分比排序输出
P 按CPU使用百分比排序输出
q 退出top

3 关闭进程

使用kill关闭某些进程

1
kill -l # 列出当前系统所支持的信号

image-20211120235300710

一共有64种信号,分为两类,不可靠信号(1-31)和可靠信号(32-64)。不可靠信号和可靠信号的区别在于前者不支持排队,可能会造成信号丢失,而后者不会(发送几次信号就收到几次)。

1
2
3
4
5
6
7
8
9
10
11
12
13
 1) SIGHUP	 2) SIGINT	 3) SIGQUIT	 4) SIGILL	 5) SIGTRAP
6) SIGABRT 7) SIGBUS 8) SIGFPE 9) SIGKILL 10) SIGUSR1
11) SIGSEGV 12) SIGUSR2 13) SIGPIPE 14) SIGALRM 15) SIGTERM
16) SIGSTKFLT 17) SIGCHLD 18) SIGCONT 19) SIGSTOP 20) SIGTSTP
21) SIGTTIN 22) SIGTTOU 23) SIGURG 24) SIGXCPU 25) SIGXFSZ
26) SIGVTALRM 27) SIGPROF 28) SIGWINCH 29) SIGIO 30) SIGPWR
31) SIGSYS 34) SIGRTMIN 35) SIGRTMIN+1 36) SIGRTMIN+2 37) SIGRTMIN+3
38) SIGRTMIN+4 39) SIGRTMIN+5 40) SIGRTMIN+6 41) SIGRTMIN+7 42) SIGRTMIN+8
43) SIGRTMIN+9 44) SIGRTMIN+10 45) SIGRTMIN+11 46) SIGRTMIN+12 47) SIGRTMIN+13
48) SIGRTMIN+14 49) SIGRTMIN+15 50) SIGRTMAX-14 51) SIGRTMAX-13 52) SIGRTMAX-12
53) SIGRTMAX-11 54) SIGRTMAX-10 55) SIGRTMAX-9 56) SIGRTMAX-8 57) SIGRTMAX-7
58) SIGRTMAX-6 59) SIGRTMAX-5 60) SIGRTMAX-4 61) SIGRTMAX-3 62) SIGRTMAX-2
63) SIGRTMAX-1 64) SIGRTMAX

这些信号里,介绍一些常用的

数字编号 信号含义 信号翻译
1 SIGHUP 一般守护进程都会在收到这个信号时重新加载配置。 (类似 reload)
9 SIGKILL 强制杀死进程(有状态的服务(存磁盘的,如mysql)强制停止可能会导致下次起不来)
15 SIGTERM 终止进程,默认kill不加参数就是这个信号

大部分程序接收到SIGTERM信号后,会先释放自己的资源,然后再停止。然而kill -9命令,系统给对应程序发送的信号是SIGKILL,不会被阻塞直接递达,所以能顺利杀掉进程。

Linux系统中的killallpkill命令用于杀死指定名字的进程。我们可以使用kill命令杀死指定进程PID的进程,如果要找到我们需要杀死的进程,我们还需要在之前使用ps等命令再配合grep来查找进程,而killallpkill把这两个过程合二为一,是一个很好用的命令。

1
2
3
4
5
6
7
8
9
10
11
12
13
# 通过服务名称杀掉进程
vim nginx.conf # 修改为worker_processes 10;
kill -1 26093 # 平滑reload nginx,可以看到很多ngixn进程
kill 26121 # 杀掉一个子进程,会迅速的被master启动起来,只是id号不一致了

kill 26093 # 主进程,子进程都会被杀掉

# 通过服务名称杀掉进程
pkill nginx
killall nginx

# 使用pkill踢出从远程登录到本机的用户,终止pts/0上所有进程, 并且bash也结束(用户被强制退出)
pkill -9 bash

附1、paramiko的简单使用

该模块可以利用python远程执行linux命令,实现自动化操作多台机器。

相关链接:官方文档github

下面是一个简单的例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
import paramiko
# 创建ssh对象
client = paramiko.SSHClient()
# 设置连接策略,允许连接不在know_hosts文件中的主机
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
# 连接远程主机
client.connect(hostname="127.0.0.1",port=22,username="xxx",password="xxx")
# 执行命令
stdin, stdout, stderr = client.exec_command('ls -l')
result = stdout.read()
print(result.decode("utf-8"))
# 关闭连接
client.close()