Linux 就该这么学(RHEL7)

[TOC]

系统环境部署

重置root管理员密码

第 1 步: 重启linux系统,引导界面按键盘e键,进入内核编辑界面。
Linux 就该这么学(RHEL7)
第 2 步: 在linux16参数这行最后追加rd.break,然后按“Ctrl + X”组合键来运行修改过的内核程序。
Linux 就该这么学(RHEL7)
第 3 步: 随后系统进入紧急救援模式。
Linux 就该这么学(RHEL7)
第 4 步: 依次输入以下命令,等待系统重启完毕,就可以使用新密码登录Linux系统了。

mount -o remount,rw /sysroot  
chroot /sysroot  
passwd  
touch /.autorelabel
exit
reboot

Linux 就该这么学(RHEL7)

RMP(红帽软件包管理器)

<center>常用的RPM软件包命令</center>

名称 命令
安装软件的命令格式 rpm -ivh filename.rpm
升级软件的命令格式 rpm -Uvh filename.rpmrpm -Uvh filename.rpm
卸载软件的命令格式 rpm -e filename.rpm
查询软件描述信息的命令格式 rpm -qpi filename.rpm
列出软件文件信息的命令格式 rpm -qpl filename.rpm
查询文件属于哪个 RPM 的命令格式 rpm -qf filename

YUM软件仓库

<center>常见的YUM命令</center>

命令 作用
yum repolist all 列出所有仓库
yum list all 列出仓库中所有软件包
yum info **软件包名称** 查看软件包信息
yum install **软件包名称** 安装软件包
yum reinstall **软件包名称** 重新安装软件包
yum update **软件包名称** 升级软件包
yum remove **软件包名称** 移除软件包
yum clean all 清除所有仓库缓存
yum check-update 检查可更新的软件包
yum grouplist 查看系统中已经安装的软件包组
yum groupinstall **软件包组** 安装指定的软件包组
yum groupremove **软件包组** 移除指定的软件包组
yum groupinfo **软件包组** 查询指定的软件包组

systemd初始化进程

Linux 系统开机过程:从BIOS开始,进入 Boot Loader,加载系统内核,然后内核初始化,最后启动初始化进程。初始化进程作为Linux系统的第一个进程,它需要完成 Linux 系统中的相关初始化工作,为用户提供合适的工作环境。RHEL7 系统选择systemd初始化进程,因此没有了“运行级别”这个概念,Linux系统在启动时要加载大量的初始化工作,如挂载文件系统和交换分区、启动各类进程服务等,这些都可以看作是一个一个单元,systemd用目标 target 来代替了 System V init 中的运行级别的概念,两者区别如下:
<center>systemd 与 System V init 的区别以及作用</center>

System V init 运行级别 systemd 目标名称 作用
0 runlevel0.target,poweroff.target 关机
1 runlevel1.target, rescue.target 单用户模式
2 runlevel2.target, multi-user.target 等同于级别3
3 runlevel3.target, multi-user.target 多用户的文本界面
4 runlevel4.target, multi-user.target 等同于级别3
5 runlevel5.target, graphical.target 多用户的图形界面
6 runlevel6.target, reboot.target 重启
emergency emergency.target 紧急 Shell

如果想要将系统的默认运行目标修改为“多用户,无图形”模式,可以直接使用ln命令把多用户模式目标文件链接到/etc/systemd/system/目录:

[root@linuxprobe ~]# ln -sf /lib/systemd/system/multi-user.target /etc/systemd/system/default.target
[root@linuxprobe ~]# systemctl get-default  //获取系统当前级别命令
multi-user.target

系统下次重启,默认就会进入“多用户,无图形”模式。
Linux 就该这么学(RHEL7)
<center>systemctl 管理服务的启用、重启、停止、重载、查看状态等常用命令</center>

System V init 命令(RHEL 6 系统) systemctl 命令(RHEL 7 系统) 作用
service foo start systemctl start foo.service 启动服务
service foo restart systemctl restart foo.service 重启服务
service foo stop systemctl stop foo.service 停止服务
service foo reload systemctl reload foo.service 重新加载配置文件(不终止服务)
service foo status systemctl status foo.service 查看服务状态

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

System V init 命令(RHEL 6 系统) systemctl 命令(RHEL 7 系统) 作用
chkconfig foo on| systemctl enable foo.service 开机自动启动
chkconfig foo off |systemctl disable foo.service 开机不自动启动
chkconfig foo| systemctl is-enabled foo.service 查看特定服务是否为开机自启动
chkconfig --list|systemctl list-unit-files --type=service 查看各个级别下服务的启动与禁用情况

查看服务运行状态

[root@linuxprobe ~]# systemctl status sshd

Shell

计算机硬件组成: 运算器、控制器、存储器、输入/输出设备.

扫描二维码关注公众号,回复: 6572847 查看本文章

系统内核: Linux内核是负责完成对硬件资源的分配、调度等管理任务的,因此系统内核对计算机的正常运行非常重要,一般不建议直接去编辑内核中的参数,而是让用户通过基于系统调用接口开发出的程序或服务来管理计算机,以满足日常工作需要。
<center>用户与 Linux 系统的交互</center>

Linux 就该这么学(RHEL7)

man 命令

<center>man 命令中的常用按键以及用途</center>

按键 用途
空格键 向下翻一页
PaGe down 向下翻一页
PaGe up 向上翻一页
home 直接前往行首
end 直接前往行尾
/ 从上往下搜索某个关键词
从上往下搜索某个关键词
n 定位到下一个搜索到的关键词
N 定位到上一个搜索到的关键词
q 退出帮助文档

<center>man 命令帮助信息的结构以及意义</center>

结构名称 代表意义
NAME 命令的名称
SYNOPSIS 参数的大致使用方法
DESCRIPTION 介绍说明
EXAMPLES 演示(附带简单说明)
OVERVIEW 概述
DEFAULTS 默认的功能
OPTIONS 具体的可用选项(带介绍)
ENVIRONMENT 环境变量
FILES 用到的文件
SEE ALSO 相关的资料
HISTORY 维护历史与联系方式

常用系统工作命令

echo 命令

echo 命令用于在终端输出字符串或变量提取后的值。

格式:“echo [字符串 | $变量]”。

例如,该命令会在终端屏幕显示“jackson”:

[root@linuxprobe ~]# echo jackson
jackson

例如,该命令会提取变量 SHELL 的值,并将其输出到屏幕上:

[root@linuxprobe ~]# echo $SHELL
/bin/bash

date 命令

date 命令用于显示及设置系统的时间或日期。

格式:“date [选项] [+指定的格式]”。

<center>date 命令中的参数以及作用</center>

参数 作用
%t 跳格[Tab 键]
%H 小时(00~23)
%I 小时(00~12)
%M 分钟(00~59)
%S 秒(00~59)
%j 今年中的第几天

例如:按照 date 命令查看系统当前时间为:

root@linuxprobe ~]# date
Wed May 22 10:55:01 EDT 2019

按照“年-月-日 小时:分钟:秒”的格式查看系统当前时间为:

[root@linuxprobe ~]# date "+%Y-%m-%d %H:%M:%S"
2019-05-22 11:01:01

将系统当前时间设置为 2019 年 5 月 23 日 23 点 30 分:

[root@linuxprobe ~]# date -s "20190523 23:30:00"
Thu May 23 23:30:00 EDT 2019
[root@linuxprobe ~]# date
Thu May 23 23:30:01 EDT 2019

date 命令中的参数%j 可用来查看今天是当年中的第几天。该参数能够很好地区分备份时间的新旧,即数字越大,越靠近当前时间。该参数的使用方式以及显示结果如下:

[root@linuxprobe ~]# date +%j
143
[root@linuxprobe ~]# date "+%j"
143

reboot 命令

reboot 命令用于重启系统。

格式: reboot。

例如,由于重启计算机这种操作会涉及硬件资源的管理权限,因此默认只能使用 root 管理员来重启:

[root@linuxprobe ~]# reboot

poweroff 命令

poweroff 命令用于关闭系统。

格式: poweroff。

例如,该命令与 reboot 命令相同,都会涉及硬件资源的管理权限,因此默认只有 root 管理员可以关闭电脑:

[root@linuxprobe ~]# poweroff 

weget 命令

wget 命令用于在终端中下载网络文件。

格式: “wget [参数] 下载地址”。

<center>wget 命令的参数以及作用</center>

参数 作用
-b 后台下载模式
-P 下载到指定目录
-t 最大尝试次数
-c 断点续传
-p 下载页面内所有资源,包括图片、视频等
-r 递归下载

例如,下载最新《Linux 就该这么学》pdf电子版:
Linux 就该这么学(RHEL7)
例如,使用 wget 命令递归下载 www.linuxprobe.com 网站内的所有页面数据以及文件,下载完成后会自动保存到当前路径下一个名为 www.linuxprobe.com 的目录中:

[root@linuxprobe ~]# wget -r -p http://www.linuxprobe.com

Linux 就该这么学(RHEL7)

ps 命令

ps 命令用于查看系统中的进程状态。

格式: “ps [参数]”。

<center>ps 命令的参数以及作用</center>

参数 作用
-a 显示所有进程(包括其他用户的进程)
-u 用户以及其他详细信息
-x 显示没有控制终端的进程

在 Linux 系统中,时刻运行着许多进程,常见的有 5 中进程状态,分别为运行、中断、不可中断、僵死与停止,其各自含义如下:

  • R(运行): 进程正在运行或在运行队列中等待。
  • S(中断): 进程处于休眠中,当某个条件形成后或者接收到信号时,则脱离该状态。
  • D(不可中断): 进程不响应系统异步信号,即便 kill 命令也不能将其中断。
  • Z(僵死): 进程已经终止,但进程描述符依然存在,直到父进程调用 wait4()系统函数后将进程释放。
  • T(停止): 进程收到停止信号后停止运行。
    <center>当执行ps aux命令后会看到如下进程状态</center>
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
进程的所有者 进程 ID 号 运算器占用率 内存占用率 虚拟内存使用量(单位是 KB) 占用的固定内存量(单位是 KB) 所在终端 进程状态 被启动的时间 实际使用 CPU 的时间 命令名称与参数
root 1 0.0 0.1 52840 6608 ? Ss May23 0:02 root 1 0.0 0.1 52840 6608 ? Ss May23 0:02 /usr/lib/systemd/systemd --switched-roo
root 2 0.0 0.0 0 0 ? S May23 0:00 [kthreadd]
root 3 0.0 0.0 0 0 ? S May23 0:00 [ksoftirqd/0]
root 5 0.0 0.0 0 0 ? S< May23 0:00 [kworker/0:0H]
root 7 0.0 0.0 0 0 ? S May23 0:00 [migration/0]

top 命令

top 命令用于动态地监视进程活动与系统负载等信息

格式: top。

例如,top命令执行结果的前5行为系统整体的统计信息,其所代表的含义如下:

  • 第1行: 系统时间、运行时间、登录终端数、系统负载(三个数值分别为1分钟、5分钟、15分钟内的平均值,数值越小,意味着负载越低)。
  • 第2行: 进程总数、运行中的进程数、睡眠中的进程数、停止的进程数、僵死的进程数。
  • 第3行: 用户占用资源百分比、系统内核占用资源百分比、改变过优先级的进程资源百分比、空闲的资源百分比(如:“100.0 id”代表有100%的 CPU 处理器资源空闲)等。
  • 第4行: 物理内存总量、内存使用量、内存空闲量、作为内存缓存的内存量。
  • 第5行: 虚拟内存总量、虚拟内存使用量、虚拟内存空闲量、已被提前加载的内存量。

    [root@linuxprobe ~]# top
    top - 08:59:39 up 5 min,  2 users,  load average: 0.02, 0.24, 0.15
    Tasks: 458 total,   1 running, 457 sleeping,   0 stopped,   0 zombie
    %Cpu(s):  0.0 us,  0.0 sy,  0.0 ni,100.0 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
    KiB Mem:   4033908 total,   618388 used,  3415520 free,      748 buffers
    KiB Swap:  2097148 total,        0 used,  2097148 free.   216592 cached Mem
    
    PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND                            
    907 root      20   0  267156   4188   3356 S   0.3  0.1   0:00.43 vmtoolsd                           
    1883 gdm       20   0 1415600 132312  33640 S   0.3  3.3   0:09.09 gnome-shell                        
    2010 root      20   0  123924   1920   1148 R   0.3  0.0   0:00.18 top                                
     1 root      20   0   52844   6608   3748 S   0.0  0.2   0:02.45 systemd      

    Linux 就该这么学(RHEL7)

    pidof 命令

    pidoff 命令用户查询某个指定服务进程的 PID 值。

格式: “pidof [参数] [服务名称]”。

例如,通过 pidof 命令查询本机上 sshd 服务的 PID:

[root@linuxprobe ~]# pidof sshd
1613

kill 命令

kill 命令用于终止某个指定 PID 的服务进程。

格式:“kill [参数] [进程 PID]” 。

例如,kill 掉 sshd 服务进程(其中进程1613是虚拟机 sshd 进程,3477是工具连接的 sshd 进程)

[root@linuxprobe ~]# pidof sshd
3477 1613
[root@linuxprobe ~]# kill 1613
[root@linuxprobe ~]# pidof sshd
3477

killall 命令

killall 命令用于终止某个指定名称的服务所对应的全部进程。

格式: “killall [参数] [服务名称]”。

例如,结束 httpd 服务全部进程:

[root@linuxprobe ~]# pidof httpd
13581 13580 13579 13578 13577 13576
[root@linuxprobe ~]# killall httpd
[root@linuxprobe ~]# pidof httpd
[root@linuxprobe ~]#

系统状态检测命令

ifconfig 命令

ifconfig 命令用于获取网卡配置与网络状态等信息。

格式: “ifconfig [网络设备] [参数]”。

例如,使用 ifconfig 命令查看本机网卡信息(主要看的是网卡名称、IP 地址、MAC 地址以及 RX、TX 的接收与发送数据包的个数及累计流量)

[root@linuxprobe ~]# 
[root@linuxprobe ~]# ifconfig
eno16777728: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.1.10  netmask 255.255.255.0  broadcast 192.168.1.255
        inet6 fe80::20c:29ff:fe22:edc0  prefixlen 64  scopeid 0x20<link>
        ether 00:0c:29:22:ed:c0  txqueuelen 1000  (Ethernet)
        RX packets 2027  bytes 146271 (142.8 KiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 2884  bytes 2825954 (2.6 MiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

uname 命令

uname 命令用于查看系统内核与系统版本等信息。

格式: “uname [-a]”。

例如,在使用 uname 命令时,一般会固定搭配 -a 参数来完整地查看当前系统的内核名称、主机名、内核发行版本、节点名、系统时间、硬件名称、硬件平台、处理器类型以及操作系统名称等信息。

[root@linuxprobe ~]# uname -a 
Linux linuxprobe.com 3.10.0-123.el7.x86_64 #1 SMP Mon May 5 11:16:57 EDT 2014 x86_64 x86_64 x86_64 GNU/Linux

例如,查看系统当前版本的详细信息:

[root@linuxprobe ~]# cat /etc/redhat-release 
Red Hat Enterprise Linux Server release 7.0 (Maipo)

uptime 命令

uptime 用于查看系统的负载信息。

格式: “uptime”。

例如,uptime 命令可以显示当前系统时间、系统已运行时间、
启用终端数量以及平均负载等信息。平均负载值指的是系统在最近1分钟、5分钟、15分钟内的压力情况;负载值越低越好,尽量不要超过1,生产环境中不要超过5。

[root@linuxprobe ~]# uptime
 10:31:57 up  1:37,  3 users,  load average: 0.19, 0.10, 0.07

free 命令

free 命令用于显示当前系统中的内存使用量信息。

格式: “free [-h]”。

例如,free -h输出信息如下:

[root@linuxprobe ~]# 
[root@linuxprobe ~]# free -h
             total       used       free     shared    buffers     cached
Mem:          3.8G       1.0G       2.8G       9.6M       792K       408M
-/+ buffers/cache:       620M       3.2G
Swap:         2.0G         0B       2.0G

<center>free -h 命令输出后的信息</center>

内存总量 已用量 可用量 进程共享的内存量 磁盘缓存的内存量 缓存的内存量
total used free shared buffers cached
Mem: 3.8G 1.0G 2.8G 9.6M 792K 408M
-/+ buffers/cache: 620M 3.2G
Swap: 2.0G 0B 2.0G

who 命令

who 用于查看当前登入主机的用户终端信息。

格式:“who [参数]”。

who 命令输出的结果

[root@linuxprobe ~]# who 
root     :0           2019-05-23 10:00 (:0)
root     pts/0        2019-05-23 10:00 (:0)
root     pts/1        2019-05-23 10:05 (192.168.1.1)
登录的用户名 终端设备 登录到系统的时间
root :0 2019-05-23 10:00 (:0)
root pts/0 2019-05-23 10:00 (:0)
root pts/1 2019-05-23 10:05 (192.168.1.1)

last 命令

last 命令用于查看所有系统的登录记录。

格式: “last [参数]”。

例如,使用 last 命令查看本机的登录记录:

[root@linuxprobe ~]# last
root     pts/1        192.168.1.1      Thu May 23 10:05   still logged in   
root     pts/1        192.168.1.1      Thu May 23 10:01 - 10:05  (00:03)    
root     pts/0        :0               Thu May 23 10:00   still logged in   
root     :0           :0               Thu May 23 10:00   still logged in   
root     pts/0        192.168.1.1      Thu May 23 08:58 - 10:00  (01:02) 

history 命令

history 命令用于显示历史执行过的命令。执行 history 命令能显示出当前用户在本地计算机中执行过的最近1000条命令记录,可以编辑/etc/profile文件自定义 HISTSIZE 变量值。如果是用-c 参数会清空所有的命令历史记录。还可以使用“!编码数字”的方式来重复执行某一次的命令。是命令会被保存到用户家目录中的.bash_history文件中。

格式:“history [-c]”。

[root@linuxprobe ~]# cat .bash_history 
[root@linuxprobe ~]# history -c

sosreport 命令

sosreoport 命令用于收集系统配置及架构信息并输出诊断文档。

格式: “sosreport”。

工作目录切换命令

pwd 命令

pwd 命令用于显示用户当前所处的工作目录。**

格式: “pwd [选项]”。

[root@linuxprobe etc]# pwd
/etc

cd 命令

cd 命令用于切换工作路径。

格式:“cd [目录名称]”。

例如,cd - 返回到上一次所处的目录:

[root@linuxprobe etc]# cd -
/home/jackson

例如:cd .. 切换到上一级目录:

[root@linuxprobe etc]# cd ..
[root@linuxprobe /]# 

例如:cd ~ 切换到当前用户家目录:

[root@linuxprobe /]# cd ~
[root@linuxprobe ~]# 

例如:cd ~username 切换到其他用户的家目录:

[root@linuxprobe ~]# cd ~jackson
[root@linuxprobe jackson]#

ls命令

ls 命令用于显示目录中的文件信息。

格式: “ls [选项] [文件]”

使用 ls 命令的 -a 参数可以查看全部文件(包括隐藏文件),使用 -l 参数可以查看文件的属性、大小等详细信息,如果想要查看目录属性信息,则需要使用 -d 参数。

例如,查看当前目录下所有文件属性信息:

[root@linuxprobe ~]# ls -al
total 19704
dr-xr-x---. 15 root root     4096 May 23 10:05 .
drwxr-xr-x. 17 root root     4096 May 24  2019 ..
-rw-------.  1 root root     1488 May 21 14:50 anaconda-ks.cfg
-rw-------.  1 root root     1423 May 23 10:05 .bash_history
-rw-r--r--.  1 root root       18 Dec 28  2013 .bash_logout
-rw-r--r--.  1 root root      176 Dec 28  2013 .bash_profile

例如,查看目录属性信息:

[root@linuxprobe ~]# ls -ld /root
dr-xr-x---. 15 root root 4096 May 23 10:05 /root

文本文件编辑命令

cat 命令

cat 命令用于查看纯文本文件(内容较少的。

格式: “cat [选项] [文件]”

例如,查看文本并且显示行号:

[root@linuxprobe ~]# cat -n /etc/passwd
     1  root:x:0:0:root:/root:/bin/bash
     2  bin:x:1:1:bin:/bin:/sbin/nologin
     3  daemon:x:2:2:daemon:/sbin:/sbin/nologin
     4  adm:x:3:4:adm:/var/adm:/sbin/nologin

more 命令

more 命令用于查看纯文本文件(内容较多的)。

格式: “more [选项] 文件”。

例如:

[root@linuxprobe ~]# more /etc/passwd
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin
games:x:12:100:games:/usr/games:/sbin/nologin
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
nobody:x:99:99:Nobody:/:/sbin/nologin
dbus:x:81:81:System message bus:/:/sbin/nologin
polkitd:x:999:998:User for polkitd:/:/sbin/nologin
unbound:x:998:997:Unbound DNS resolver:/etc/unbound:/sbin/nologin
colord:x:997:996:User for colord:/var/lib/colord:/sbin/nologin
usbmuxd:x:113:113:usbmuxd user:/:/sbin/nologin
avahi:x:70:70:Avahi mDNS/DNS-SD Stack:/var/run/avahi-daemon:/sbin/nologin
avahi-autoipd:x:170:170:Avahi IPv4LL Stack:/var/lib/avahi-autoipd:/sbin/nologin
--More--(49%)

head 命令

head 命令用于查看纯文本文档的前N行内容。

格式: “head [选项] [文件]”。

例如,查看/etc/passwd文件前5行:

[root@linuxprobe ~]# head -n 5 /etc/passwd
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
[root@linuxprobe ~]# 

tail 命令

tail 命令用户查看纯文本文档的后N行或持续刷新内容。

格式: “tail [选项] [文件]”。

例如:

[root@linuxprobe ~]# tail -n 1 /etc/passwd
jackson:x:1000:1000:jackson:/home/jackson:/bin/bash
[root@linuxprobe ~]# tail -f /var/log/messages 
May 24 09:52:29 linuxprobe systemd: Started Session 1 of user root.
May 24 09:52:33 linuxprobe chronyd[952]: Selected source 185.255.55.20
May 24 09:53:38 linuxprobe chronyd[952]: Selected source 120.24.166.46
May 24 09:57:15 linuxprobe NetworkManager[1119]: <info> NetworkManager state is now CONNECTED_GLOBAL
May 24 09:57:15 linuxprobe goa[2060]: goa-daemon version 3.8.5 starting [main.c:113, main()]
May 24 09:57:15 linuxprobe goa[2060]: GoaKerberosIdentityManager: Using polling for change notification for credential cache type 'KEYRING' [goakerberosidentitymanager.c:1393, monitor_credentials_cache()]
May 24 10:00:02 linuxprobe systemd: Starting Session 2 of user root.
May 24 10:00:02 linuxprobe systemd: Started Session 2 of user root.
May 24 10:01:01 linuxprobe systemd: Starting Session 3 of user root.
May 24 10:01:01 linuxprobe systemd: Started Session 3 of user root.

tr 命令

tr 命令用于替换文本文件中的字符。**

格式:“tr [原始字符] [目标字符]”。

例如,将/etc/passwd中的字母全部替换为小写:

[root@linuxprobe tmp]# cp /etc/passwd .
[root@linuxprobe tmp]# cat passwd | tr [a-z] [A-Z]
ROOT:X:0:0:ROOT:/ROOT:/BIN/BASH
BIN:X:1:1:BIN:/BIN:/SBIN/NOLOGIN
DAEMON:X:2:2:DAEMON:/SBIN:/SBIN/NOLOGIN
ADM:X:3:4:ADM:/VAR/ADM:/SBIN/NOLOGIN
LP:X:4:7:LP:/VAR/SPOOL/LPD:/SBIN/NOLOGIN
SYNC:X:5:0:SYNC:/SBIN:/BIN/SYNC
SHUTDOWN:X:6:0:SHUTDOWN:/SBIN:/SBIN/SHUTDOWN
HALT:X:7:0:HALT:/SBIN:/SBIN/HALT
MAIL:X:8:12:MAIL:/VAR/SPOOL/MAIL:/SBIN/NOLOGIN
OPERATOR:X:11:0:OPERATOR:/ROOT:/SBIN/NOLOGIN
GAMES:X:12:100:GAMES:/USR/GAMES:/SBIN/NOLOGIN
FTP:X:14:50:FTP USER:/VAR/FTP:/SBIN/NOLOGIN
NOBODY:X:99:99:NOBODY:/:/SBIN/NOLOGIN
DBUS:X:81:81:SYSTEM MESSAGE BUS:/:/SBIN/NOLOGIN
POLKITD:X:999:998:USER FOR POLKITD:/:/SBIN/NOLOGIN
UNBOUND:X:998:997:UNBOUND DNS RESOLVER:/ETC/UNBOUND:/SBIN/NOLOGIN
COLORD:X:997:996:USER FOR COLORD:/VAR/LIB/COLORD:/SBIN/NOLOGIN
USBMUXD:X:113:113:USBMUXD USER:/:/SBIN/NOLOGIN
AVAHI:X:70:70:AVAHI MDNS/DNS-SD STACK:/VAR/RUN/AVAHI-DAEMON:/SBIN/NOLOGIN
AVAHI-AUTOIPD:X:170:170:AVAHI IPV4LL STACK:/VAR/LIB/AVAHI-AUTOIPD:/SBIN/NOLOGIN
LIBSTORAGEMGMT:X:996:994:DAEMON ACCOUNT FOR LIBSTORAGEMGMT:/VAR/RUN/LSM:/SBIN/NOLOGIN
SASLAUTH:X:995:76:"SASLAUTHD USER":/RUN/SASLAUTHD:/SBIN/NOLOGIN
QEMU:X:107:107:QEMU USER:/:/SBIN/NOLOGIN
RPC:X:32:32:RPCBIND DAEMON:/VAR/LIB/RPCBIND:/SBIN/NOLOGIN
RPCUSER:X:29:29:RPC SERVICE USER:/VAR/LIB/NFS:/SBIN/NOLOGIN
NFSNOBODY:X:65534:65534:ANONYMOUS NFS USER:/VAR/LIB/NFS:/SBIN/NOLOGIN
RTKIT:X:172:172:REALTIMEKIT:/PROC:/SBIN/NOLOGIN
RADVD:X:75:75:RADVD USER:/:/SBIN/NOLOGIN
NTP:X:38:38::/ETC/NTP:/SBIN/NOLOGIN
CHRONY:X:994:993::/VAR/LIB/CHRONY:/SBIN/NOLOGIN
ABRT:X:173:173::/ETC/ABRT:/SBIN/NOLOGIN
PULSE:X:171:171:PULSEAUDIO SYSTEM DAEMON:/VAR/RUN/PULSE:/SBIN/NOLOGIN
GDM:X:42:42::/VAR/LIB/GDM:/SBIN/NOLOGIN
GNOME-INITIAL-SETUP:X:993:991::/RUN/GNOME-INITIAL-SETUP/:/SBIN/NOLOGIN
POSTFIX:X:89:89::/VAR/SPOOL/POSTFIX:/SBIN/NOLOGIN
SSHD:X:74:74:PRIVILEGE-SEPARATED SSH:/VAR/EMPTY/SSHD:/SBIN/NOLOGIN
TCPDUMP:X:72:72::/:/SBIN/NOLOGIN
JACKSON:X:1000:1000:JACKSON:/HOME/JACKSON:/BIN/BASH

wc 命令

wc 命令用于统计指定文本的行数、字数、字节数。

格式: “wc [参数] 文本”。

<center>wc 的参数以及作用</center>

参数 作用
-l 只显示行数
-w 只显示单词数
-c 只显示字节数

例如,查看/etc/passwd有多少个用户

[root@linuxprobe ~]# wc -l /etc/passwd
38 /etc/passwd

stat 命令

stat 命令用于查看文件的具体存储信息和时间等信息。

格式:“stat 文件名称”。

例如:

[root@linuxprobe ~]# stat /etc/passwd
  File: ‘/etc/passwd’
  Size: 1917        Blocks: 8          IO Block: 4096   regular file
Device: 803h/2051d  Inode: 137016694   Links: 1
Access: (0644/-rw-r--r--)  Uid: (    0/    root)   Gid: (    0/    root)
Context: system_u:object_r:passwd_file_t:s0
Access: 2019-05-23 23:30:10.742716385 -0400
Modify: 2019-05-21 14:50:18.925040916 -0400
Change: 2019-05-21 14:50:18.925040916 -0400
 Birth: -

cut 命令

cut 命令用户按“列”提取文本字符。

格式:“cut [参数] 文本”。

例如,提取/etc/passwd文件的用户姓名,即第1列:

[root@linuxprobe ~]# cut -d: -f1 /etc/passwd
root
bin
daemon
adm
lp
sync
shutdown
halt
mail
operator
games
ftp
nobody
dbus
polkitd
unbound
colord
usbmuxd
avahi
avahi-autoipd
libstoragemgmt
saslauth
qemu
rpc
rpcuser
nfsnobody
rtkit
radvd
ntp
chrony
abrt
pulse
gdm
gnome-initial-setup
postfix
sshd
tcpdump
jackson

diff 命令

diff 命令用于比较多个文本文件的差异。

格式:“diff [参数] 文件”。

例如,使用--brief参数显示比较厚的结果,判断文件是否相同:

[root@linuxprobe tmp]# cat diff_A
Welcome to linuxprobe.com
Red Hat certified
Free Linux Lessons
Professional guidance
Linux Cours
[root@linuxprobe tmp]# cat diff_B
Welcome to linuxprobe.com

Red Hat certified
Free Linux Lessons
///////....///////
Professional guidance
Linux Cours
[root@linuxprobe tmp]# diff --brief diff_A diff_B
Files diff_A and diff_B differ

最后,使用-c参数描述文件内容具体不同之处:

[root@linuxprobe tmp]# diff -c diff_A diff_B
*** diff_A  2019-05-24 10:30:00.975297809 -0400
--- diff_B  2019-05-24 10:35:32.797468642 -0400
***************
*** 1,5 ****
--- 1,7 ----
  Welcome to linuxprobe.com
+ 
  Red Hat certified
  Free Linux Lessons
+ ///////....///////
  Professional guidance
  Linux Cours

文件目录管理命令

touch 命令

touch 命令用于创建空白文件或设置文件的时间。

格式:“touch [选项] [文件]”。

<center>touch 命令的参数与其作用</center>

参数 作用
-a 仅修改“读取时间”(atime)
-m 仅修改“修改时间”(mtime )
-d 同时修改atime与mtime

例如:

  [root@linuxprobe tmp]# touch -d "2019-03-22 23:23" passwd 
[root@linuxprobe tmp]# ll passwd 
-rw-r--r--. 1 root root 1917 Mar 22 23:23 passwd

mkdir 命令

mkdir 命令用于创建空白的目录。

格式: “mkdir [选项] 目录”。

例如,还可以使用-p参数来递归创建出具有嵌套层关系的文件目录:

[root@linuxprobe tmp]# mkdir linuxprobe
[root@linuxprobe tmp]# mkdir -p /a/b/c

cp 命令

cp 命令用于复制文件或目录。

格式:“cp [选项] 源文件 目标文件”。

<center>cp 命令的参数及其作用</center>

参数 作用
-p 保留原始文件的属性
-d 若对象为“链接文件”,则保留该“链接文件”的属性
-r 递归持续复制(用于目录)
-i 若目标文件存在则询问是否覆盖
-a 相当于-pdr(p、d、r为上述参数)

例如,创建名为“test_A.log”的空白文件,并将其复制为一份名为test_B.log的备份文件:

[root@linuxprobe ~]# touch test_A.log
[root@linuxprobe ~]# cp test_A.log test_B.log
[root@linuxprobe ~]# ls
anaconda-ks.cfg  Documents  initial-setup-ks.cfg  Music     Public     test_A.log  Videos
Desktop          Downloads  LinuxProbe.pdf        Pictures  Templates  test_B.log  www.linuxprobe.com

mv 命令

mv 命令用于剪切文件或将文件重命名。

格式:“mv [选项] 源文件 [目标路径|目标文件名]”。

例如,将"test_A.log"重命名为“1.log”:

[root@linuxprobe ~]# mv test_A.log 1.log
[root@linuxprobe ~]# ls
1.log            Documents             LinuxProbe.pdf  Public      Videos
anaconda-ks.cfg  Downloads             Music           Templates   www.linuxprobe.com
Desktop          initial-setup-ks.cfg  Pictures        test_B.log

rm 命令

rm 命令用于删除文件或目录。

格式:“rm [选项] 文件”。

使用 rm 命令删除文件时,系统默认会询问是否要执行删除操作,可以使用-f参数来强制删除,另外要删除一个目录,需要使用-r参数进行删除,否则删除不掉。

例如:

[root@linuxprobe ~]# rm 1.log
rm: remove regular empty file ‘1.log’? y
[root@linuxprobe ~]# rm -f test_B.log

dd 命令

dd 命令用于按照之地当大小和个数的数据块来复制文件或转换文件。

格式:“dd [参数]”。
<center>dd 命令的参数及其作用</center>

参数 作用
if 输入文件名称
of 输出文件名称
bs 设置每个“块”的大小
count 设置要复制“块”的个数

例如,使用dd命令从/dev/zero设备文件中取出一个大小为100M的数据块,然后保存成名为100_file的文件:

[root@linuxprobe ~]# dd if=/dev/zero of=100M_file count=1 bs=100M
1+0 records in
1+0 records out
104857600 bytes (105 MB) copied, 2.96847 s, 35.3 MB/s
[root@linuxprobe ~]# du -sh 100M_file 
100M    100M_file

file 命令

file 命令用于查看文件的类型。

格式:“file 文件名”。

例如:

[root@linuxprobe ~]# file LinuxProbe.pdf 
LinuxProbe.pdf: PDF document, version 1.7
[root@linuxprobe ~]# file anaconda-ks.cfg 
anaconda-ks.cfg: ASCII text[root@linuxprobe ~]# file LinuxProbe.pdf 
LinuxProbe.pdf: PDF document, version 1.7
[root@linuxprobe ~]# file anaconda-ks.cfg 
anaconda-ks.cfg: ASCII text

打包压缩与搜索命令

tar 命令

tar 命令用于对文件进行打包压缩或解压。

格式:“tar [选项] [文件]”。

<center>tar 命令的参数及其作用</center>

参数 作用
-c 创建压缩文件
-x 解开压缩文件
-t 查看压缩包内有哪些文件
-z 用Gzip压缩或解压
-j 用bzip2压缩或解压
-v 显示压缩或解压过程
-f 目标文件名
-p 保留原始的权限与属性
-P 使用绝对路径来压缩
-C 指定解压到的目录

-c参数用于创建压缩文件,-x参数用户解压文件,这两个参数不能同时使用,-z参数指定使用 Gzip 格式来压缩或解压文件,-j参数指定使用

例如,将/etc下所有文件打包成“etc.tar.gz”格式:

[root@linuxprobe ~]# tar -czvf etc.tar.gz /etc

例如,将打包好的文件解压到/tmp下:

[root@linuxprobe ~]# tar -xzvf etc.tar.gz -C /tmp

grep 命令

grep 命令用于在文本中执行关键词搜素,并显示匹配的结果。

格式:“grep [选项] [文件]”。

<center>grep 命令的参数及其作用</center>

参数 作用
-b 将可执行文件(binary)当做(text)来搜索
-c 仅显示找到的行数
-i 忽略大小写
-n 显示行号
-v 反向选择-->仅仅列出没有“关键词”的行

-n参数用来显示搜索到信息的行号,-v参数用于反选信息(即没有关键词的所有行)

例如,通过/etc/passwd文件,查找出当前系统不被允许登录到系统的所有用户信息:

[root@linuxprobe ~]# grep "/sbin/nologin" /etc/passwd //等同于grep /sbin/nologin /etc/passwd
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin
games:x:12:100:games:/usr/games:/sbin/nologin

find 命令

find 命令用于按照指定条件来查找文件。

格式:“find [查找路径] 寻找条件”。

<center>find 命令中的参数及其作用</center>

参数 作用
-name 匹配名称
-perm 匹配权限(mode 为完全匹配,-mode为包含即可)
-user 匹配所有者
-group 匹配所有组
-mtime -n +n 匹配修改内容的时间(-n指n天以内,+n指n天以前)
-atime -n +n 匹配访问文件的时间(-n指n天以内,+n指n天以前)
-ctime -n +n 匹配修改文件权限的时间(-n指n天以内,+n指n天以前)
-nouser 匹配无所有者的文件
-nogroup 匹配无所有组的文件
-newer f1 !f2 匹配比文件f1新比f2旧的文件
-type b/d/c/p/l/f 匹配文件类型(后面的字母参数依次表示块设备、目录、字符设备、管道符、链接文件、文本文件)
-size 匹配文件的大小(+50KB为查找超过 50KB 的文件,而-50KB 为查找小于 50KB 的文件)
-prune 忽略某个文件
-exec ... {}\; 后面可跟用于进一步处理搜索结果的命令

例如,获取/etc下以“host”开头的文件:

[root@linuxprobe ~]# find /etc/ -name "host*"
/etc/avahi/hosts
/etc/host.conf
/etc/hosts
/etc/hosts.allow
/etc/hosts.deny
/etc/selinux/targeted/modules/active/modules/hostname.pp
/etc/hostname

例如,搜索整个系统中权限包括SUID权限的所有文件,只需使用-4000:

[root@linuxprobe ~]# find / -perm -4000

例如:

[root@linuxprobe ~]# mkdir -p /tmp/jackson
[root@linuxprobe ~]# find / -user jackson -exec cp -a {} /tmp/jackson/ \;
find: ‘/proc/3394/task/3394/fd/6’: No such file or directory
find: ‘/proc/3394/task/3394/fdinfo/6’: No such file or directory
find: ‘/proc/3394/fd/6’: No such file or directory
find: ‘/proc/3394/fdinfo/6’: No such file or directory
cp: ‘/tmp/jackson/.mozilla’ and ‘/tmp/jackson/.mozilla’ are the same file
cp: ‘/tmp/jackson/.bash_logout’ and ‘/tmp/jackson/.bash_logout’ are the same file
cp: ‘/tmp/jackson/.bash_profile’ and ‘/tmp/jackson/.bash_profile’ are the same file
cp: ‘/tmp/jackson/.bashrc’ and ‘/tmp/jackson/.bashrc’ are the same file
cp: ‘/tmp/jackson/extensions’ and ‘/tmp/jackson/extensions’ are the same file
cp: ‘/tmp/jackson/plugins’ and ‘/tmp/jackson/plugins’ are the same file
cp: cannot overwrite non-directory ‘/tmp/jackson/jackson’ with directory ‘/home/jackson’

管道符、重定向与环境变量

重定向技术的五种模式:

  • 标准覆盖输出重定向
  • 标准追加输出重定向
  • 错误覆盖输出重定向
  • 错误追加输出重定向
  • 输入重定向

输入输出重定向

输入重定向是指把文件导入到命令中,而输出重定向是指把原本要输出到屏幕的数据信息写入到指定文件中。日常学习和工作中,使用输出重定向的频率更高。而输出重定向又可以分为标准输出重定向和错误输出重定向两种不同的技术。**

  • 标准输入重定向(STDIN,文件描述符为0): 默认从键盘输入,也可从其他文件或命令输入。
  • 标准输出重定向(STDOUT,文件描述符为1): 默认输出到屏幕。
  • 错误输出重定向(STDERR,文件描述符为2): 默认输出到屏幕。

<center>输入重定向中用到的符号及其作用</center>

符号 作用
命令 < 文件 将文件作为命令的标准输入
命令 << 分界符 从标准输入中读入,知道遇见分界符才停止
命令 < 文件1 > 文件2 将文件1作为命令的标准输入并将标准输出到文件2

<center>输出重定向中用到的符号及其作用</center>

符号 作用
命令 > 文件 将标准输出重定向到一个文件中(清空原有文件的数据)
命令 2>文件 将错误输出重定向到一个文件中(清空原有文件的数据)
命令 >> 文件 将标准输出重定向到一个文件中(追加到原有内容的后面)
命令 2>> 文件 将错误输出重定向到一个文件中(追加到原有内容的釉面)
命令 >> 文件 2>&1 或 命令 &>> 文件 将标准输出与错误输出共同写入到文件中(追加到原有内容的后面)

对于重定向中的标准输出模式,可以省略描述符 1 不写,而错误输出模式的文件描述符 2 必须要写。

[root@linuxprobe ~]# man bash &gt;&gt; readme.txt
[root@linuxprobe ~]# cat readme.txt 

例如,将报错信息写入到文件(注意:&gt;前面不能有空格)

[root@linuxprobe ~]# ll xxx 2&gt; /tmp/stderr.txt  //管道符`&gt;`前面不能有空格
[root@linuxprobe ~]# cat /tmp/stderr.txt 
ls: cannot access xxx: No such file or directory

例如,将文件“readme.txt”导入给wc -l命令,统计一下行数:

[root@linuxprobe ~]# wc -l &lt;readme.txt 
4462    //相当于cat readme.txt |wc -l

管道符命令

按下键盘的 Shift + \ 键就可以输入管道符

格式: “命令 A | 命令 B ”。

例如:找出被限制登录系统的用户数:

[root@linuxprobe ~]# grep "/sbin/nologin" /etc/passwd | wc -l
33

例如,以翻页形式查看/etc目录中的内容:

[root@linuxprobe ~]# ls -l /etc/ |more
total 1400
drwxr-xr-x.  3 root root       97 May 21 14:46 abrt
-rw-r--r--.  1 root root       16 May 21 14:50 adjtime
-rw-r--r--.  1 root root     1518 Jun  7  2013 aliases
-rw-r--r--.  1 root root    12288 May 21 07:06 aliases.db
drwxr-xr-x.  2 root root       49 May 21 14:45 alsa
drwxr-xr-x.  2 root root     4096 May 21 14:47 alternatives
-rw-------.  1 root root      541 Jan 27  2014 anacrontab
-rw-r--r--.  1 root root       55 Jan 29  2014 asound.conf
-rw-r--r--.  1 root root        1 Jan 29  2014 at.deny
drwxr-xr-x.  2 root root       31 May 21 14:46 at-spi2
drwxr-x---.  3 root root       41 May 21 14:45 audisp
drwxr-x---.  3 root root       79 May 21 15:06 audit
drwxr-xr-x.  4 root root       94 May 21 14:45 avahi
drwxr-xr-x.  2 root root     4096 May 21 14:48 bash_completion.d
-rw-r--r--.  1 root root     2835 Mar 12  2014 bashrc
drwxr-xr-x.  2 root root        6 Apr  2  2014 binfmt.d
drwxr-xr-x.  2 root root       39 May 21 14:46 bluetooth
drwxr-xr-x.  2 root root       41 May 21 14:44 bonobo-activation
drwxr-xr-x.  2 root root    12288 May 21 14:46 brltty
--More--

例如,使用管道符重置密码:

[root@linuxprobe ~]# echo "linuxprobe" | passwd --stdin root
Changing password for user root.
passwd: all authentication tokens updated successfully.

例如,邮件发送:

[root@linuxprobe ~]# echo "content" |mail -s "i learn linux study hard" jackson
[root@linuxprobe ~]# su - jackson
Last login: Sat May 25 05:28:53 EDT 2019 on pts/2
[jackson@linuxprobe ~]$ mail
Heirloom Mail version 12.5 7/5/10.  Type ? for help.
"/var/spool/mail/jackson": 3 messages 1 new 3 unread
 U  1 root                  Sat May 25 05:08  21/657   "wangzhixin"
 U  2 root                  Sat May 25 05:22  19/596   "this is my world"
>N  3 root                  Sat May 25 05:30  18/588   "i learn linux study hard"
& 

例如:

[root@linuxprobe ~]# mail -s "readme" [email protected] <<over
> i think linux is very practical
> i hope i can pass rhcsa for my study hard!
> over

命令行的通配符

通配符就是通用的匹配信息的符号。

  • *星号():** 代表匹配零个或多个字符;
  • 问号(?): 代表匹配单个字符;
  • [0-9]: 中括号内加数字,代表匹配0到9之间的单个数字的字符;
  • [abc]: 中括号内加字母,代表匹配三个字符中的任意一个字符。

例如,匹配"/dev"下以“sda”开都的文件:

[root@linuxprobe ~]# ls -l /dev/sda*
brw-rw----. 1 root disk 8, 0 May 24 19:56 /dev/sda
brw-rw----. 1 root disk 8, 1 May 24 19:56 /dev/sda1
brw-rw----. 1 root disk 8, 2 May 24 19:56 /dev/sda2
brw-rw----. 1 root disk 8, 3 May 24 19:56 /dev/sda3

例如:

[root@linuxprobe ~]# ls -l /dev/sda?
brw-rw----. 1 root disk 8, 1 May 24 19:56 /dev/sda1
brw-rw----. 1 root disk 8, 2 May 24 19:56 /dev/sda2
brw-rw----. 1 root disk 8, 3 May 24 19:56 /dev/sda3

例如:

[root@linuxprobe ~]# ls -l /dev/sda[0-9]
brw-rw----. 1 root disk 8, 1 May 24 19:56 /dev/sda1
brw-rw----. 1 root disk 8, 2 May 24 19:56 /dev/sda2
brw-rw----. 1 root disk 8, 3 May 24 19:56 /dev/sda3

例如:

[root@linuxprobe ~]# ls -l /dev/sda[135]
brw-rw----. 1 root disk 8, 1 May 24 19:56 /dev/sda1
brw-rw----. 1 root disk 8, 3 May 24 19:56 /dev/sda3

常用的转义字符

4个常用的转义字符:

  • 反斜杠(\): 使反斜杠后面的一个变量变为单纯的字符串。
  • 单引号("): 转义其中所有的变量为单纯的字符串。
  • 双引号(""): 保留其中的变量属性,不进行转义处理。
  • 反引号(``): 吧其中的命令执行后返回结果。

例如:

[root@linuxprobe ~]# price=5
[root@linuxprobe ~]# echo "price is $price"
price is 5

例如:

[root@linuxprobe ~]# echo '$price'
$price

例如:

[root@linuxprobe ~]# echo "price is \$$price"
price is $5

例如:

[root@linuxprobe ~]# echo `uname -a`
Linux linuxprobe.com 3.10.0-123.el7.x86_64 #1 SMP Mon May 5 11:16:57 EDT 2014 x86_64 x86_64 x86_64 GNU/Linux

重要的环境变量

变量是计算机系统用于保存可变值得数据类型。Linux 系统中,变量名称一般都是大写的。Linux 系统中的环境变量是用来定义系统运行环境的一些参数,比如用户不同的家目录、邮件存放位置等。

Linux 系统执行命令分为 4 个步骤
第 1 步: 判断用户是否以绝对路径或相对路径的方式输入命令(如/bin/ls),如果是的话,则直接执行。

第 2 步: Linux 系统检查用户输入的命令是否为“别名命令”,即用一个自定义的命令名称来替换原本的命令名称。可以使用 alias命令来创建一个属于自己的命令别名,
格式: “alias 别名=命令”。

若要取消一个命令别名,则使用unalias命令,

格式: “unalias 别名”。

第 3 步: Bash 解释器判断用户输入的是内部命令还是外部命令。内部命令是解释器内部的指令,会被直接执行;而用户绝大部分时间输入的是外部命令,这些命令交由步骤 4 继续处理。可以使用“ type 命令名称”来判断用户输入的命令是内部命令还是外部命令。

第 4 步: 系统在多个路径中查找用户输入的命令文件,而定义浙西路径的变量叫做PATH,可以简单地把它理解成是“解释器的小助手”,作用是告诉 Bash 解释器待执行的命令可能存放的位置,然后 Bash 解释器就会在这些位置逐个查找。PATH是由多个路径值组成的变量,每个路径值之间用冒号间隔开,对这些路径的增加和删除操作将影响到 Bash 解释器对 Linux 命令的查找。
例如:

[root@linuxprobe ~]# echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
[root@linuxprobe ~]# PATH=$PATH:/root/bin
[root@linuxprobe ~]# echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin:/root/bin
[root@linuxprobe ~]# 

<center>Linux 系统中最重要的 10 个环境变量</center>

变量名称 作用
HOME 用户的主目录(即家目录)
SHELL 用户在使用的 Shell 解释器名称
HISTSIZE 输出的历史命令记录条数
HISTFILESIZE 保存的历史命令记录条数
MAIL 邮件保存路径
LANG 系统语言、语系名称
RANDOM 生成一个随机数字
PS1 Bash 解释器的提示符
PATH 定义解释器搜索用户执行命令的路径
EDITOR 用户默认的文本编辑器

例如,设置一个名称为 WORKDIR 的变量:

[root@linuxprobe ~]# mkdir /home/workdir
[root@linuxprobe ~]# WORKDIR=/home/workdir
[root@linuxprobe ~]# cd $WORKDIR
[root@linuxprobe workdir]# pwd
/home/workdir

例如,将以上变量提升为全局变量:

[root@linuxprobe ~]# export WORKDIR
[root@linuxprobe ~]# su - jackson
[jackson@linuxprobe ~]$ cd $WORKDIR
[jackson@linuxprobe workdir]$ pwd
/home/workdir

Vim 编辑器与 Shell 命令脚本

Vim 文本编辑器

Vim 编辑器三种模式:

  • 命令模式: 控制光标移动,可对文本进行复制、粘贴、删除和查找等工作。
  • 输入模式: 正常的文本录入。
  • 末行模式: 保存或退出文档,以及设置编辑环境。

<center>Vim 编辑器模式的切换方法</center>

Linux 就该这么学(RHEL7)

<center>Vim 中常用的命令</center>

命令 作用
dd 删除(剪切)光标所在整行
5dd 删除(剪切)从光标处开始的后5行
yy 复制光标所在整行
5yy 复制从光标处开始的后5行
n 显示搜索命令定位到下一个字符串
N 显示搜索命令定位到上一个字符串
u 撤销上一步操作
p 将之前删除(dd)或复制(yy)过的数据粘贴到光标后面

<center>末行模式中可用的命令</center>

命令 作用
: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
?字符串 在文本中从下至上搜索该字符
/字符串 在该文本中从上至下搜索该字符串

配置主机名称

为了在局域网查找某台特定的主机,或者对主机进行区分,处理要有 IP 地址外,还要为主机配置一个主机名,主机名之间可以通过这个类似于域名的名称来相互访问。其中,主机名大多保存/etc/hostname中。

配置网卡信息

网卡配置信息保存在/etc/sysconfig/network-scripts/ifcfg-eno16777728文件中。
例如,编辑网卡信息:

[root@linuxprobe ~]# vim /etc/sysconfig/network-scripts/ifcfg-eno16777728
TYPE=Ethernet   //设备类型
BOOTPROTO=static    //地址分配模式
NAME=eno16777728    //网卡名称
ONBOOT=yes  //是否启动
IPADDR=192.168.1.10 //IP 地址
NETMASK=255.255.255.0   //子网掩码
GATEWAY=192.168.1.2 //网关地址
DNS1=192.168.1.2    //DNS 地址

重启网络并测试网络是否能联通:

[root@linuxprobe ~]# systemctl restart network
[root@linuxprobe ~]# ping 192.168.1.10
PING 192.168.1.10 (192.168.1.10) 56(84) bytes of data.
64 bytes from 192.168.1.10: icmp_seq=1 ttl=64 time=0.039 ms
64 bytes from 192.168.1.10: icmp_seq=2 ttl=64 time=0.043 ms

配置 Yum 软件仓库

Yum 软件仓库的作用是为了进一步简化 RPM 管理软件的难度以及自动分析所需软件包及其依赖关系的技术。

例如,搭建并配置 Yum 软件仓库步骤:

第 1 步:/etc/yum.repos.d/目录下新建一个以.repo结尾的文件。

[root@linuxprobe ~]# vim /etc/yum.repos.d/rhel7.repo
[rhel7]
name=rhel7
baseurl=file:///media/cdrom
enabled=1
gpgcheck=0
  • [rhel7]:Yum 软件仓库的唯一标识符,避免与其他仓库冲突。
  • name=rhel7:Yum 软件仓库的名称描述,易于识别仓库用处。
  • baseurl=file:///media/cdrom:提供的方式包括 FTP(ftp://..)、HTTP(http://..)、本地(file:///..)
  • enabled=1:设置此源是否可用;1 为可用,0 为禁用。
  • gpgcheck=1:设置此源是否检验文件;1 为检验,0 为不校验。
  • gpgkey=file:///media/cdrom/RPM-GPG-KEY-redhat-release:若上面的参数开启校验,那么请指定公钥文件地址。

第 2 步: 按照配置信息挂载光盘,并把光盘挂载信息写入到/etc/fstab文件中

第 3 步: 创建挂载点并设置开机自动挂载

[root@linuxprobe ~]# mkdir /media/cdrom
[root@linuxprobe ~]# mount /dev/cdrom /media/cdrom/
mount: /dev/sr0 is write-protected, mounting read-only
[root@linuxprobe ~]# vim /etc/fstab 
[root@linuxprobe ~]# tail -n 1 /etc/fstab 
/dev/cdrom  /media/cdrom    iso9660 defaults    0   0

第 4 步: 查看 Yum 源是否可用

[root@linuxprobe ~]# yum list
Loaded plugins: langpacks, product-id, subscription-manager
This system is not registered to Red Hat Subscription Management. You can use subscription-manager to register.
Installed Packages
GConf2.x86_64                                         3.2.6-8.el7                           @anaconda/7.0
ModemManager.x86_64                                   1.1.0-6.git20130913.el7               @anaconda/7.0
ModemManager-glib.x86_64                              1.1.0-6.git20130913.el7               @anaconda/7.0
NetworkManager.x86_64                                 1:0.9.9.1-13.git20140326.4dba720.el7  @anaconda/7.0
NetworkManager-config-server.x86_64                   1:0.9.9.1-13.git20140326.4dba720.el7  @anaconda/7.0
NetworkManager-glib.x86_64                            1:0.9.9.1-13.git20140326.4dba720.el7  @anaconda/7.0
NetworkManager-libreswan.x86_64                       0.9.8.0-5.el7                         @anaconda/7.0
NetworkManager-tui.x86_64                             1:0.9.9.1-13.git20140326.4dba720.el7  @anaconda/7.0
ORBit2.x86_64        

编写 Shell 脚本

Shell 脚本命令的两种工作方式:

  • 交互式(Interactive):用户每输入一条命令就立即执行一次。
  • 批处理(Batch):由用户事先编写好一个完整的 Shell 脚本,Shell 会一次性执行脚本中的诸多的命令。

例如,查看 Shell 变量可以发现当前系统默认使用 Bash 作为命令行终端解释器:

[root@linuxprobe ~]# echo $SHELL
/bin/bash

编写简单的脚本

[root@linuxprobe ~]# vim examlpe.sh
#!/bin/bash
# this is example bash shell
pwd
ls -al
[root@linuxprobe ~]# bash examlpe.sh[root@linuxprobe ~]# ./examlpe.sh
-bash: ./examlpe.sh: Permission denied
[root@linuxprobe ~]# chmod u+x examlpe.sh 
[root@linuxprobe ~]# ./examlpe.sh 

接收用户的参数

为了让 Shell 脚本程序更好地满足用户的一些实时需求,以便灵活完成工作,必须要让脚本程序能够像之前执行命令一样,接收用户输入的参数。

*例如,$0 对应的是当前 Shell 脚本程序的名称,$# 对应的是总共有几个参数,$ 对应的是所有位置的参数值,$? 对应的是显示上一次命令的执行返回值,而 $1、$2、$3...则分别对应着第 N 个位置的参数值。**

例如,

[root@linuxprobe ~]# vim example.sh
#!/bin/bash
echo "当前脚本名称为$0"
echo "总共有$#个参数,分别是$*。"
echo "第 1 个参数为$1,第 5 个为$5。"
[root@linuxprobe ~]# sh example.sh one two three four five six
当前脚本名称为example.sh
总共有6个参数,分别是one two three four five six。
第 1 个参数为one,第 5 个为five。

判断用户参数

如,系统在执行 mkdir命令时会判断用户输入的信息,即判断用户指定的文件夹名称是否存在,如果存在则提示报错;反之则自动创建。Shell 脚本中的条件测试语法可以判断表达式是否成立,若条件成立则返回数字 0,否则便返回其他随机数值。

格式(条件测试语句的执行格式):[ 条件表达式 ],注意,两边应该有一个空格

按照测试对象来分,条件测试语句可以分为 4 种:

  • 文件测试语句(文件测试即使用指定条件来判断文件是否存在或权限是否满足等情况的运算符);
  • 逻辑测试语句;
  • 整数值比较语句;
  • 字符串比较语句。

<center>文件测试所用的参数</center>

运算符 作用
-d 测试文件是否为目录类型
-e 测试文件是否存在
-f 判断是否为一般文件
-r 测试当前用户是否有权限读取
-w 测试当前用户是否有权限写入
-x 测试当前用户是否有权限执行

例如,使用文件测试语句判断/etc/fstab是否为一个目录类型的文件,然后通过 Shell 解释器的内设$?变量显示上一条命令执行后的返回值。如果返回值为 0,则目录存在;如果返回值为非零的值,则意味着目录不存在

[root@linuxprobe ~]# [ -d /etc/fstab ]
[root@linuxprobe ~]# echo $?
1

判断/etc/fstab是否为一般文件,如果返回值为 0,则表示文件存在,且为一般文件:

[root@linuxprobe ~]# [ -f /etc/fstab ]
[root@linuxprobe ~]# echo $?
0

逻辑测试语句用于对测试结果进行逻辑分析,根据测试结果过可实现不同的效果。例如在 Shell 终端中逻辑"与"的运算符号&&,它表示当前面的命令执行成功后才会执行它后面的命令

例如,可以用来判断/etc/cdrom文件是否存在,若存在输出 Exit 字样:

[root@linuxprobe ~]# [ -e /dev/cdrom ] && echo Exit
Exit

处理逻辑"与"外,还有逻辑"或",它在 Linux 系统中的运算符号为||,表示当前面的命令执行失败后才会执行它后面的命令。

例如,结合系统环境变量 USER 判断当前登录用户是否为非管理员身份:

[root@linuxprobe ~]# echo $USER
root
[root@linuxprobe ~]# [ $USER = root ] || echo "user" 
[root@linuxprobe ~]# su - jackson
Last login: Sat May 25 05:35:50 EDT 2019 on pts/2
[jackson@linuxprobe ~]$ [ $USER = root ] || echo "user"
user

第三种个逻辑语句是"非",在 Linux 系统中的运算符号是一个叹号!,它表示把条件测试中的判断结果取相反值。也就是说如果原本测试结果是正确的,则将其变成错误的;原本测试错误的的结果则将其变成正确的。

例如:

[root@linuxprobe ~]# [ ! $USER = root ] || echo "administrator"     //本次结果返回值应该为 administrator,实际返回值为空,有待测试
[root@linuxprobe ~]# 

整数比较运算符仅仅是对数字的操作,不能将数字与字符串、文件等内容一起操作,而且不能想当然地使用日常生活中的等号、大于号、小于号等来判断。因为等号与复制命令符冲突,大于号和小于号与输出重定向和输入重定向命令符冲突。因此一定要使用规范的整数比较运算符来进行操作。

<center>可用的整数比较运算符</center>

-eq 是否等于
-ne 是否不等于
-gt 是否大于
-lt 是否小于
-le 是否等于或小于
-ge 是否大于或等于

例如,测试 10 是否 10 以及 10 是否 等于 10

[root@linuxprobe ~]# [ 10 -gt 10 ]
[root@linuxprobe ~]# echo $?
1
[root@linuxprobe ~]# [ 10 -eq 10 ] 
[root@linuxprobe ~]# echo $?
0

例如, free 命令,它可以用来获取当前系统正在使用及可用的内存量信息。
接下来先使用 free -m 命令查看内存使用量情况(单位为 MB),然后通过 grep Mem:命令过滤
出剩余内存量的行,再用 awk '{print $4}'命令只保留第四列,最后用 FreeMem=语句的方式
把语句内执行的结果赋值给变量:

[root@linuxprobe ~]# free -m
             total       used       free     shared    buffers     cached
Mem:          3939        728       3210          8          0        247
-/+ buffers/cache:        480       3459
Swap:         2047          0       2047
[root@linuxprobe ~]# free -m | grep Mem:
Mem:          3939        728       3210          8          0        247
[root@linuxprobe ~]# free -m | grep Mem: | awk '{print $4}'
3210
[root@linuxprobe ~]# FreeMem=`free -m | grep Mem | awk '{print $4}'`
[root@linuxprobe ~]# echo $FreeMem 
3210

例如,利用以上案例,判断内存是否小于 4096,若小于则会提示“Insufficient Memory”(内存不足)的字样:

[root@linuxprobe ~]# [ $FreeMem -lt 4096 ] && echo "Insufficient Memory"
Insufficient Memory

<center>常见的字符串比较运算符</center>

运算符 作用
= 比较字符串内容是否相同
!= 比较字符串内容是否不同
-z 判断字符串内容是否为空

例如,通过 String 变量判断是否为空值:

[root@linuxprobe ~]# [ -z $String ]
[root@linuxprobe ~]# echo $?
0

流程控制语句

if 条件测试语句

if 条件测试语句可以让脚本根据实际情况自动执行相应的命令。if 语句分为单分支结构、双分支结构、多分支结构,if 条件语句的单分支结构有if、then、fi 关键词组成。

<center>单分支的 if 语句</center>

Linux 就该这么学(RHEL7)

例如,使用单分支 if 条件语句来判断/media/cdrom1文件是否存在,若存在就结束条件判断和整个 Shell 脚本,反之则去创建这个目录:

[root@linuxprobe ~]# 
[root@linuxprobe ~]# ls /media
cdrom
[root@linuxprobe ~]# vim mkcdrom1.sh 
#!/bin/bash
DIR="/media/cdrom1"
if [ ! -e $DIR ]
then 
mkdir -p $DIR
fi
[root@linuxprobe ~]# bash mkcdrom1.sh 
[root@linuxprobe ~]# ls /media/
cdrom  cdrom1

if 条件语句的双分支结构由if、then、else、fi 关键词组成,它进行一次条件匹配判断,如果与条件匹配,则去执行相应的预设命令;反之则去执行不匹配时的预设命令,相当于口语中的“如果...那么...或者...那么...”

<center>双分支的 if 语句</center>

Linux 就该这么学(RHEL7)

例如,使用双分支 if 语句验证某台主机是否在线,然后根据返回值的结果,要么显示主机在线,要么显示主机不在线信息。使用ping命令检测,通过-c参数规定尝试的次数;-i参数定义每个数据包发送的间隔;-W参数定义等待超时时间:

[root@linuxprobe ~]# vim chkhost.sh 
ping -c 3 -i 0.2 -W 2 $1 &> /dev/null
if [ $? -eq 0 ]   
then
echo "Host $1 is On-line"
else
echo "Host $1 is Off-line"
fi
[root@linuxprobe ~]# bash chkhost.sh 192.168.1.2
Host 192.168.1.2 is On-line
[root@linuxprobe ~]# bash chkhost.sh 192.168.2.1
Host 192.168.2.1 is Off-line

if 条件语句的多分支结构由if、then、else、elif、fi 关键词组成,它进行多次条件匹配判断,多次判断中的任何一项在匹配成功后都会执行相应的预设命令,相当于口语的“如果...那么...如果...那么”。

<center>多分支的 if 语句</center>

Linux 就该这么学(RHEL7)

例如,使用多分支 if 条件语句判断用户输入的分数在哪个成绩范围区间内,然后输入如Excellent、Pass、Fail 等提示信息。Linux 系统中,read 命令是用来读取用户输入信息的命令,能够把接收到的用户输入信息赋值给后面的指定变量,-p参数用于向用户显示一定的提示信息:

[root@linuxprobe ~]# vim chkscore.sh 
#!/bin/bash
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
[root@linuxprobe ~]# sh chkscore.sh
Enter your score (0~100):90
90 is Excellent
[root@linuxprobe ~]# sh chkscore.sh
Enter your score (0~100):80
80 is Pass
[root@linuxprobe ~]# sh chkscore.sh
Enter your score (0~100):60
60 is Fail

例如,增加分数大于100或小于0则显示报错字样:

[root@linuxprobe ~]# vim chkscore.sh 
#!/bin/bash
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"
elif [ $GRADE -gt 100 ] ; then
echo "$GRADE is Error(more than 100)"
elif [ $GRADE -lt 0 ] ; then
echo "$GRADE is Error(less than 0)"
else
echo "$GRADE is Fail"
fi
[root@linuxprobe ~]# sh chkscore.sh
Enter your score (0~100):90
90 is Excellent
[root@linuxprobe ~]# sh chkscore.sh
Enter your score (0~100):80
80 is Pass
[root@linuxprobe ~]# sh chkscore.sh
Enter your score (0~100):60
60 is Fail
[root@linuxprobe ~]# sh chkscore.sh
Enter your score (0~100):200
200 is Error(more than 100)
[root@linuxprobe ~]# sh chkscore.sh
Enter your score (0~100):-1
-1 is Error(less than 0)

for 条件循环语句

for 条件循环语句允许脚本一次性读取多个信息,然后逐一对信息进行操作处理,当处理的数据有范围时,使用 for 循环语句。

<center>for 循环语句的语法格式</center>

Linux 就该这么学(RHEL7)

例如,使用 for 循环语句批量创建用户

[root@linuxprobe ~]# vim Example.sh
#!/bin/bash
read -p "Enter The Users Password : " 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@linuxprobe ~]# bash Example.sh 
Enter The Users Password : root11
andy , Create Success
barry , Create Success
carl , Create Success
duke , Create Success
eric , Create Success
george , Create Success

例如,利用双分支 if 条件语句与 for 循环语句相结合,自动测试主机是否在线:

[root@linuxprobe ~]# vim ipadds.txt 
192.168.1.2
192.168.1.1
192.168.2.1
192.168.2.10
192.168.1.10
[root@linuxprobe ~]# vim CheckHosts.sh#!/bin/bash
HLIST=$(cat ipadds.txt)
for IP in $HLIST
do
ping -c 3 -i 0.2 -W 3 $IP &> /dev/null
if [ $? -eq 0 ] ; then
echo "Host $IP is On_line"
else
echo "Host $IP is Off-line"
fi
done
[root@linuxprobe ~]# chmod u+x CheckHosts.sh
[root@linuxprobe ~]# ./CheckHosts.sh 
Host 192.168.1.2 is On_line
Host 192.168.1.1 is On_line
Host 192.168.2.1 is Off-line
Host 192.168.2.10 is Off-line
Host 192.168.1.10 is On_line

while 条件循环语句

while 条件循环语句是一种让脚本根据某些条件来重复执行命令的语句,它的循环结构往往在执行前并不确定最终执行的次数,完全不同于 for 循环语句中有目标、有范围的使用场景。while 循环语句通过判断条件测试的真假来决定是否继续执行命令,若条件为真就继续执行,为假就结束循环。

<center>while 循环语句的语法格式</center>

Linux 就该这么学(RHEL7)

计划任务服务程序

在指定时间段内自动启用或停止某些服务或命令,从而实现运维的自动化。

例如,编写一个用来猜测数值大小的脚本 Guess.sh。该脚本使用$RANDOM 变量来调取出一个随机的数值(范围为 0~32767),将这个随机数对 1000 进行取余操作,并使用 expr 命令取得其结果,再用这个数值与用户通过 read命令输入的数值进行比较判断。这个判断语句分为三种情况,分别是判断用户输入的数值是等于、大于还是小于使用 expr 命令取得的数值。当前,现在这些内容不是重点,我们当前要关注的是while 条件循环语句中的条件测试始终为 true,因此判断语句会无限执行下去,直到用户输入的数值等于 expr 命令取得的数值后,这两者相等之后才运行 exit 0 命令,终止脚本的执行:

[root@linuxprobe ~]# vim Guess.sh
#!/bin/bash
PRICE=$(expr $RANDOM % 1000)
TIMES=0
echo "商品价格为0~1200之间,猜猜看是多少?"
while true
do
read -p "请输入您猜测的价格数目:" INT
let TIMES++
if  [ $INT -eq $PRICE ] ; then
echo "恭喜您答对了,实际价格是 $PRICE"
echo "您总共猜 g $TIMES 次"
exit 0
elif [ $INT -gt $PRICE ] ; then
echo "太高了!"
else
echo “太低了!”
fi
done
[root@linuxprobe ~]# bash Guess.sh 
商品价格为0~1200之间,猜猜看是多少?
请输入您猜测的价格数目:600
“太低了!”
请输入您猜测的价格数目:900
太高了!
请输入您猜测的价格数目:800
“太低了!”
请输入您猜测的价格数目:850
太高了!
请输入您猜测的价格数目:830
太高了!
请输入您猜测的价格数目:820
恭喜您答对了,实际价格是 820
您总共猜 g 6 次

case 条件测试语句

case 语句是在多个范围内匹配数据,若匹配成功则执行相关命令并结束整个条件测试;而如果数据不在所列出的范围内,则会去执行星号(*)中所定义的默认命令。

<center>case 条件测试语句的语法结构</center>

Linux 就该这么学(RHEL7)

例如,编写脚本 Checkkeys.sh,提示用户输入一个字符并将其赋值给变量 KEY,
然后根据变量 KEY 的值向用户显示其值是字母、数字还是其他字符:

[root@linuxprobe ~]# vim CheckKey.sh 
#!/bin/bash
read -p "请输入一个字符、并按 Enter 键确认:" KEY
case "$KEY" in
[a-z]|[A-Z])
echo "您输入的是 字母。"
;;
[0-9])
echo "您输入的是 数字。"
;;
*)
echo "您输入的是 空格、功能键或其他控制字符。"
esac
[root@linuxprobe ~]# bash CheckKey.sh
请输入一个字符、并按 Enter 键确认:a
您输入的是 字母。
[root@linuxprobe ~]# bash CheckKey.sh
请输入一个字符、并按 Enter 键确认:8
您输入的是 数字。
[root@linuxprobe ~]# bash CheckKey.sh
请输入一个字符、并按 Enter 键确认: 
您输入的是 空格、功能键或其他控制字符。

计划任务分类

  • 一次性计划任务
  • 长期性计划任务

例如,一次性计划任务案例:

[root@linuxprobe ~]# at 23:59   //方式一
at> systemctl restart httpd
at> //此处请同事按下 Ctrl + D 组合键来结束编写计划任务
job 1 at Fri May 31 00:00:00 2019
[root@linuxprobe ~]# at -l
1   Fri May 31 00:00:00 2019 a root
[root@linuxprobe ~]# echo "systemctl restart httpd" | at 00:00   //方式二
job 2 at Fri May 31 00:00:00 2019
[root@linuxprobe ~]# at -l
1   Fri May 31 00:00:00 2019 a root
2   Fri May 31 00:00:00 2019 a root
[root@linuxprobe ~]# atrm 1 //删除一次性计划任务
[root@linuxprobe ~]# at -l
2   Fri May 31 00:00:00 2019 a root

<center>crond 设置任务的参数说明</center>

==口诀:分、时、日、月、星期、命令==
Linux 就该这么学(RHEL7)

<center>字段说明</center>

字段 说明
取值为 0~59 的整数
取值为 0~23 的任意整数
取值为 1~31 的任意整数
取值为 1~12 的任意整数
星期 取值为 0~7 的任意整数,其中 0 与 7 均为星期日
命令 要执行的命令或脚本

例如,每周一、三、五凌晨 3 点 25分,使用tar打包/etc/下所有文件:

[root@linuxprobe ~]# crontab -e
[root@linuxprobe ~]# crontab -l
25  3   *   *   1,3,5   /usr/bin/tar -czvf etc.passswd.tar.gz /etc

注意: 在 crond 服务的计划任务参数中,所有命令一定要使用绝对路径的方式来写,如果不知道绝对路径,使用whereis命令可以进行查询。计划任务中的“分”字段必须要有数值,绝对不能为空或者是“*”号,而“日”和“星期”字段不能同时使用,否则就会发生冲突。

用户×××与文件权限

用户 UID

Linux 系统的管理员之所以是 root,并不是名字是 root,而是因为该用户的身份号码即 UID(User IDentification)的数值为 0。在 Linux 系统中,UID 相当于我们的×××号码一样具有唯一性,因此可以通过 UID 来判断用户身份。

RHEL 7中,用户身份有如下:

  • 管理员 UID 为 0:系统的管理员用户。
  • 系统用户 UID 为1~999:Linux 系统为了避免某个服务程序出现漏洞而被***提权至整台服务器,默认服务程序会有独立的系统用户负责运行,进而有效控制被破坏范围。
  • 普通用户 UID 从 1000 开始:是由管理员创建的用用户日常工作的用户。

注意: UID 是不能冲突的,而且普通用户 UID 默认是从 1000 开始的(即使前面有空闲的号码)。

用户 GID

为了方便管理属于同一组的用户,Linux 系统引入了用户组的概念。通过使用用户组号码 GID(Group IDentification),我们可以把多个用户加入到同一个组中,从而方便为组中的用户统一规划权限或指定任务。

另外,在 Linux 系统中创建每个用户时,将自动创建一个与其同名的基本用户组,而且这个用户组只有该用户一个人。如果该用户以后被纳入其他用户组,则这个其他用户组称之为扩展用户组。一个用户只有一个基本用户组,但是可以有多个扩展用户组。

useradd 命令

useradd 命令用于创建新的用户。使用该命令创建用户账户时,默认的用户家目录存放在/home目录中,默认的 Shell 解释器为/bin/bash,而且默认会创建一个与该用户同名的基本用户组。

格式:“useradd [选项] 用户名”

<center>useradd 命令中的用户参数以及作用</center>

参数 作用
-d 指定用户的家目录(默认为/home/username)
-e 账户的到期时间,格式为YYYY-MM-DD
-u 指定该用户的默认 UID
-g 指定一个初始的用户基本组(必须已存在的组)
-G 指定一个或多个扩展用户组
-N 不创建与用户同名的基本用户组
-s 指定该用户的默认 Shell 解释器

groupadd 命令

groupadd 命令用于创建用户组。

格式:“groupadd [选项] 组名”。

usermod 命令

usermod 命令用于修改用户的属性。

格式:“usermod [选项] 用户名”。

<center>usermod 命令中的参数</center>

参数 作用
-c 填写用户账户的备用信息
-d -m 参数 -m 与 -d 连用,可重新制定用户的家目录并自动把旧的数据转移过去
-e 账户的到期时间,格式为YYYY-MM-DD
-g 变更所属用户组
-G 变更扩展用户组
-L 锁定用户禁止其登录系统
-U 解锁用户,允许其登录系统
-s 变更默认终端
-u 修改用户的 UID

passwd 命令

passwd 命令用于修改用户密码、过期时间、认证信息等。

格式:“passwd [选项] [用户名]”。

passwd 命令中的参数以及作用

参数 作用
-l 锁定用户,禁止其登录
-u 解除锁定,允许用户登录
--stdin 允许通过标准输入修改用户密码,如 echo “password” passwd --stdin username
-d 使该用户可用空密码登录系统
-e 强制用户在下次登录时修改密码
-S 显示用户的密码是否被锁定,以及密码所采用的加密算法名称

userdel 命令

userdel 命令用于删除用户。

格式:“userdel [选项] 用户名”。

userdel 命令的参数以及作用

参数 作用
-f 强制删除用户
-r 同时删除用户及用户家目录

例如:

[root@linuxprobe ~]# id duke
uid=1004(duke) gid=1004(duke) groups=1004(duke)
[root@linuxprobe ~]# ll /home
total 4
drwx------.  3 andy    andy      74 May 29 11:06 andy
drwx------.  3 barry   barry     74 May 29 11:06 barry
drwx------.  3 carl    carl      74 May 29 11:06 carl
drwx------.  3 duke    duke      74 May 29 11:06 duke
drwx------.  3 eric    eric      74 May 29 11:06 eric
drwx------.  3 george  george    74 May 29 11:06 george
drwx------. 14 jackson jackson 4096 Jun  3 09:55 jackson
[root@linuxprobe ~]# userdel -r duke
[root@linuxprobe ~]# ll /home
total 4
drwx------.  3 andy    andy      74 May 29 11:06 andy
drwx------.  3 barry   barry     74 May 29 11:06 barry
drwx------.  3 carl    carl      74 May 29 11:06 carl
drwx------.  3 eric    eric      74 May 29 11:06 eric
drwx------.  3 george  george    74 May 29 11:06 george
drwx------. 14 jackson jackson 4096 Jun  3 09:55 jackson
[root@linuxprobe ~]# 

文件权限与归属

Linux 系统中一切都是文件,但是每个文件的类型不尽相同,因此 Linux 系统使用了不同的字符来加以区分,常见的字符如下:

  • -:普通文件。
  • d:目录文件。
  • l:链接文件。
  • b:块设备文件。
  • c:字符设备文件。
  • p:管道文件。

Linux 系统中,每个文件都有所属的所有者和所有组,并且规定了文件的所有者、所有组以及其他人对文件所拥有的可读(r)、可写(w)、可执行(x)等权限。

文件权限的字符与数字表示
<table border="1" bordercolor="red">
<tr align="center">
<th>权限分配</th>
<th colspan="3">文件所有者</th>
<th colspan="3">文件所属组</th>
<th colspan="3">其他用户</th>
</tr>
<tr align="center">
<td>权限项</td>
<td>读</td>
<td>写</td>
<td>执行</td>
<td>读</td>
<td>写</td>
<td>执行</td>
<td>读</td>
<td>写</td>
<td>执行</td>
</tr>
<tr align="center">
<td>字符表示</td>
<td>r</td>
<td>w</td>
<td>x</td>
<td>r</td>
<td>w</td>
<td>x</td>
<td>r</td>
<td>w</td>
<td>x</td>
</tr>
<tr align="center">
<td>数字表示</td>
<td>4</td>
<td>2</td>
<td>1</td>
<td>4</td>
<td>2</td>
<td>1</td>
<td>4</td>
<td>2</td>
<td>1</td>
</tr>
</table>

文件的特殊权限

在复杂的生产环境中,单纯设置文件的 rwx 权限无法满足对安全和灵活性的需求,于是便有了 SUID、SGIDHE SBIT 的特殊权限位。这是一种对文件权限进行设置的特殊功能,可以与一般权限同时使用,以弥补一般权限不能实现的功能。

SUID

SUID 是一种对二进制程序设置的特殊权限,可以让二进制程序的执行者临时拥有属主的权限(仅对拥有执行权限的二进制程序有效)。

SGID

SGID 主要实现以下两种功能:

  • 让执行者临时拥有属组的权限(对拥有执行权限的二进制程序进行设置);
  • 在某个目录中创建的文件自动继承该目录的用户组(只可以对目录进行设置)。

例如,使用管理员用户创建一个目录,设置 777 权限(确保普通用户可以向其中写入文件),并为该目录设置了 SGID 特殊权限位后,切换一个普通用户,尝试在该目录中创建文件并查看创建爱你的文件是否会继承新创建的文件所在的目录的所属组名称:

[root@linuxprobe tmp]# mkdir testdir/
[jackson@linuxprobe testdir]$ echo "testwangzhixin" >test
-bash: test: Permission denied
[root@linuxprobe tmp]# chmod -Rf 777 testdir/
[root@linuxprobe tmp]# chmod -Rf g+s testdir/
[root@linuxprobe tmp]# ll -d testdir/
drwxrwsrwx. 2 root root 6 Jun  4 07:01 testdir/
[jackson@linuxprobe testdir]$ echo "testwangzhixin" >test
[jackson@linuxprobe testdir]$ ll test 
-rw-rw-r--. 1 jackson root 15 Jun  4 07:17 test
[jackson@linuxprobe testdir]$ cat test 
testwangzhixin

chmod 命令

chmod 命令能够用来设置文件或目录的权限。

格式:“chmod [参数] 权限 文件或目录名称”。

chown 命令

chown 命令可以设置文件或目录的所有者和所属组。

格式:“chown [参数] 所有者:所属组 文件或目录名称” 。

chmod 和 chown 命令是用于修改文件属性和权限的最常用命令,他们还有个共性,就是针对目录进行操作时需要加上大写参数 -R 来表示递归操作,即对目录内所有的文件进行整体操作。

SBIT

SBIT 特殊权限位可确保用户只能删除自己的文件,而不能删除其他用户的文件(如,共享目录)。
例如,RHEL 7 系统中的/tmp目录作为一个共享目录,默认已经设置了 SBIT 特殊权限位,因此除非是该目录的所有者,否则无法删除这里面的文件。

[root@linuxprobe ~]# ll -d /tmp
drwxrwxrwt. 12 root root 4096 Jun  4 09:42 /tmp

同理,可以对其他新建的目录设置 SBIT 特殊权限位:

[root@linuxprobe ~]# mkdir /linux
[root@linuxprobe ~]# ll -d /linux/
drwxr-xr-x. 2 root root 6 Jun  4 09:47 /linux/
[root@linuxprobe ~]# chmod -R o+t /linux/
[root@linuxprobe ~]# ll -d /linux/
drwxr-xr-t. 2 root root 6 Jun  4 09:47 /linux/

文件的隐藏属性

Linux 系统中的文件除了具备一般权限和特殊权限之外,还有一种隐藏权限,即被隐藏起来的权限,默认情况下不能直接被用户发觉。

chattr 命令

chattr 命令用于设置文件的隐藏权限。如果想要把某个隐藏功能添加到文件上,则需在命令后面追加“+参数”;而把某个隐藏功能移出文件,则需要追加“-参数”即可。

格式:“chattr [参数] 文件”。
<center>chattr 命令中用于隐藏权限的参数及其作用</center>

参数 作用
i 无法对文件进行修改;若对目录设置了该参数,则仅能修改其中的子文件内容而不能新建或删除文件
a 仅允许补充(追加)内容,无法覆盖/删除内容(Append Only)
S 文件内容再变更后立即同步到硬盘(sync)
s 彻底从硬盘中删除,不可恢复(用 0 填充原文件所在硬盘区域)
A 不在修改这个文件或目录的最后访问时间(alime)
b 不再修改文件或目录的存取时间
D 检查压缩文件中的错误
d 使用 dump 命令备份时忽略本文件/目录
c 默认将文件或目录进行压缩
u 当删除该文件后依然保留其在硬盘中的数据,方便日后恢复
t 让文件系统支持尾部合并(tail-merging)
X 可以直接访问压缩文件中的内容

例如:

[root@linuxprobe tmp]# echo "test" > test
[root@linuxprobe tmp]# rm test
rm: remove regular file ‘test’? y
[root@linuxprobe tmp]# echo "test" > test
[root@linuxprobe tmp]# chattr +a test
[root@linuxprobe tmp]# rm test
rm: remove regular file ‘test’? y
rm: cannot remove ‘test’: Operation not permitted

lsattr 命令

lsattr 命令用于显示文件的隐藏权限。在 Linux 系统中,文件的隐藏属性必须使用 lsattr 命令来查看。

格式:“lsattr [参数] 文件”。

[root@linuxprobe tmp]# lsattr test
-----a---------- test
[root@linuxprobe tmp]# chattr -a test
[root@linuxprobe tmp]# lsattr test
---------------- test
[root@linuxprobe tmp]# rm -f test

文件访问控制列表

一般权限、特殊权限、隐藏权限都有一个共性-->权限是针对某一类用户设置的。如果希望对某个指定用户进行单独的权限控制,就需要用到文件的访问控制列表(ACL)。通俗来讲,基于普通文件或目录设置 ACL 其实就是针对指定的用户或用户组设置文件或目录的操作权限。如果针对某个目录设置了 ACL,则目录中的文件会继承其 ACL;若针对文件设置了 ACL,则文件不再继承其所在目录的 ACL。

例如,在没有设置 root 管理员家目录 ACL 之前,普通用户是进不去 root 家目录的:

[root@linuxprobe ~]# su - jackson
Last login: Tue Jun  4 07:10:10 EDT 2019 on pts/1
[jackson@linuxprobe ~]$ cd /root
-bash: cd: /root: Permission denied

setfacl 命令

setfacl 命令用于管理文件的 ACL 规则。使用 setfacl 命令可以针对单一用户或用户组、单一文件或目录来进行读/写/执行权限的控制。其中,针对目录需要使用 -R 递归参数;针对普通文件则需使用 -m 参数;如果想要删除某个文件的 ACL,则可以使用 -b 参数。

格式:“setfacl [参数] 文件名称”。

例如,设置普通用户在/root目录上的权限(可以使用看到设置 ACL 权限,文件的权限后面的“.”变成了“+”)

[root@linuxprobe ~]# setfacl -Rm u:jackson:rwx /root/
[root@linuxprobe ~]# su - jackson
Last login: Wed Jun  5 09:35:28 EDT 2019 on pts/0
[jackson@linuxprobe ~]$ cd /root
[jackson@linuxprobe root]$ ls

[root@linuxprobe ~]# ll -d /root
dr-xr-x---. 15 root root 4096 Jun  5 09:34 /root

getfacl 命令

getfacl 命令用于显示文件上设置的 ACL 信息。

格式:“getfacl 文件名称”。

例如:

[root@linuxprobe ~]# getfacl /root
getfacl: Removing leading '/' from absolute path names
# file: root
# owner: root
# group: root
user::r-x
user:jackson:rwx
group::r-x
mask::rwx
other::---

su 命令与 sudo 服务

su 命令可以解决切换用户身份的需求,使得当前用户在不退出登录的情况下,顺畅地切换到其他用户。

例如,从 root 管理员切换至普通用户:

[root@linuxprobe ~]# id 
uid=0(root) gid=0(root) groups=0(root) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
[root@linuxprobe ~]# su - jackson
Last login: Wed Jun  5 09:48:27 EDT 2019 on pts/0
[jackson@linuxprobe ~]$ id 
uid=1000(jackson) gid=1000(jackson) groups=1000(jackson) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023

上面的 su 命令与用户名之间有一个减号(-),这意味着完全切换到新的用户,即把环境变量信息也变更为新用户的相应信息,而不是保留原始的信息。强烈建议在切换用户身份时添加减号(-)。另外从 root 管理员切换到普通用户时是不需要密码验证的,而从普通用户切换到 root 管理员就需要进行密码验证。

sudo 命令用于给普通用户提供额外的权限来完成原本 root 管理员才能完成的任务。

格式: “sudo [参数] 命令名称”。

sudo 服务中的可用参数以及作用
参数 作用
-h 列出帮助信息
-l 列出当前用户可执行的命令
-u 用户名或 UID 值 以指定的用户身份执行命令
-k 清空密码的有效时间,下次执行 sudo 时需要再次进行密码验证
-b 在后台执行指定的命令
-p 更改询问密码的提示语

sudo 命令具有一下功能:

  • 限制用户执行指定的命令;
  • 记录用户执行的每一条命令;
  • 配置文件/etc/sudoers提供集中的用户管理、权限与主机等参数;
  • 验证密码的后 5 分钟(默认值)无须再让用户再次验证密码。

    只有 root 管理员才可以使用 visudo 命令编辑 sudo 服务的配置文件。

使用 visudo 命令配置 sudo 命令的配置文件时,其操作方法与 Vim 编辑器中的方法一致,格式如下:

谁可以使用 允许使用的主机=(以谁的身份) 可执行的命令列表

[root@linuxprobe ~]# visudo     //在第 99 行添加如下内容;
     97 ## Allow root to run any commands anywhere
     98 root    ALL=(ALL)       ALL
     99 jackson ALL=(ALL)       ALL
[root@linuxprobe ~]# su - jackson   切换到普通用户;
[jackson@linuxprobe ~]$ sudo -l     //使用命令查看;
[sudo] password for jackson:        //注意:此处输入的是普通用户的密码;
Matching Defaults entries for jackson on this host:
    requiretty, !visiblepw, always_set_home, env_reset, env_keep="COLORS DISPLAY HOSTNAME HISTSIZE INPUTRC KDEDIR
    LS_COLORS", env_keep+="MAIL PS1 PS2 QTDIR USERNAME LANG LC_ADDRESS LC_CTYPE", env_keep+="LC_COLLATE
    LC_IDENTIFICATION LC_MEASUREMENT LC_MESSAGES", env_keep+="LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER LC_TELEPHONE",
    env_keep+="LC_TIME LC_ALL LANGUAGE LINGUAS _XKB_CHARSET XAUTHORITY", secure_path=/sbin\:/bin\:/usr/sbin\:/usr/bin

User jackson may run the following commands on this host:
    (ALL) ALL
[jackson@linuxprobe ~]$ ls /root        //验证是否能查看管理员 root 目录;
CheckHosts.sh  Desktop    Downloads  ipadds.txt  Pictures  Templates  test.sh
CheckKey.sh    Documents  Guess.sh   Music       Public    test       Videos

以上普通用户权限太高了,也不符合权限赋予的原则,即尽可能少地赋予权限,因此 ALL 参数不太合适,如只赋予 cat 权限:

[root@linuxprobe ~]# whereis cat
cat: /usr/bin/cat /usr/share/man/man1/cat.1.gz /usr/share/man/man1p/cat.1p.gz
[root@linuxprobe ~]# visudo     //在第 99 行添加如下内容;
     97 ## Allow root to run any commands anywhere
     98 root    ALL=(ALL)       ALL
     99 jackson ALL=(ALL)   /usr/bin/cat
[jackson@linuxprobe ~]$ cat /etc/shadow
cat: /etc/shadow: Permission denied
[jackson@linuxprobe ~]$ sudo cat /etc/shadow |more
root:$6$rthjdDAe$Sma2vFvEHgnAooxDQW6D6Kgp0A4P1TEo96.Kxo.OCh5W2CRxTHt4U07nYf7J9ySthkiVQOe1O9ZX9gl3YdDa2/:18041:0:99999:7:
::
bin:*:16141:0:99999:7:::
daemon:*:16141:0:99999:7:::
adm:*:16141:0:99999:7:::
lp:*:16141:0:99999:7:::
sync:*:16141:0:99999:7:::
shutdown:*:16141:0:99999:7:::

存储结构与磁盘划分

<center>Linux 系统中的文件存储结构</center>

Linux 就该这么学(RHEL7)
<center>Linux 系统中常见的目录名称以及相应的内容</center>

目录名称 应放置文件的内容
/boot 开机所需文件 - - 内核、开机菜单以及所需配置文件等
/dev 以文件形式存放任何设备与接口
/etc 配置文件
/home 用户家目录
/bin 存放单用户模式下还可以操作的命令
/lib 开机时用到的函数库,以及 /bin 与 /sbin 下面的命令要调用的函数
/sbin 开机过程中需要的命令
/media 用于挂载设备文件的目录
/opt 放置第三方的软件
/root 系统管理员的家目录
/srv 一些网络服务的数据文件目录
/tmp 任何人均可使用的“共享”临时目录
/proc 虚拟文件系统,例如系统内核、进程、外部设备及网络状态等
/usr/local 用户自行安装的软件
/usr/sbin Linux 系统开机时不会使用到的软件/命令/脚本
/usr/share 帮助与说明文件,也可放置共享文件
/var 主要存放经常变化的文件,如日志
/lost+found 当文件系统发生错误时,将一些丢失的文件片段存放在这里

路径的概念

路径指的是如何定位到某个文件,分为绝对路径和相对路径。绝对路径指的是从根目录(/)开始写起的文件或目录名称,而相对路径则指的是相对于当前路径的写法。

物理设备的命名规则

在 Linux 系统中一切皆文件,硬件设备也不列外。既然是文件,就必须又文件名称。系统内核中的 udev 设备管理器会自动把硬件名称规范起来,目的是让用户通过设备文件的名字可以猜出设备大致的属性以及分区信息等;另外, udev 设备管理器的服务会一直以守护进程的形式运行并侦听内核发出的信号来管理/dev目录下的设备文件。

<center>常见的硬件设备及其文件名称</center>

硬件设备 文件名称
IDE 设备 /dev/hd[a - d]
SCSI/SATA/U 盘 /dev/sd[a - p]
软驱 /dev/fd[0 - 1]
打印机 /dev/lp[0 - 15]
光驱 /dev/cdrom
鼠标 /dev/mouse
磁带机 /dev/st0/dev/ht0

现在 IDE 设备很少见了,所以一般的硬盘设备都是以“/dev/sd”开头的。

一台主机可以又多块硬盘,因此系统采用 a ~ p 来代表 16 块不同的硬盘(默认从 a 开始分配)

硬盘的分区编号规则

  • 主分区或扩展分区的编号从 1 开始,到 4 结束;
  • 逻辑分区从编号 5 开始。

注意:

  • /dev 目录中 sda 设备之所以是 a,并不是由插槽决定的,而是由系统内核的识别顺序来决定的,而恰巧很多主板的插槽顺序就是系统内核的识别顺序,因此才会被命为/dev/sda
  • 分区的编号代表分区的个数。 但是这个理论是错误的,因为分区的数字编码不一定是强制顺延下来的,也有可能是手工指定的。如 sda3 只能表示是编号为 3 的分区,而不能判断 sda 设备上存在了 3 个分区。

设备文件名称
Alt

/dev/目录中保存的应当是硬件设备文件;其次,sd 表示是存储设备;然后,a 表示系统中同类接口中第一个被识别到的设备,最后,5 表示这个设备是一个逻辑分区。一言以蔽之,“/dev/sda5”表示的就是“这是系统中第一块被识别到的硬件设备中分区编号为 5 的逻辑分区的设备文件”。

硬盘设备知识点

硬盘设备是由大量的扇区组成的,每个扇区的容量为 512 字节。其中第一个扇区最重要,它里面保存着主引导记录与分区表信息。就第一个扇区来讲,主引导记
录需要占用 446 字节,分区表为 64 字节,结束符占用 2 字节;其中分区表中每记录一个分区
信息就需要 16 字节,这样一来最多只有 4 个分区信息可以写到第一个扇区中,这 4 个分区就
是 4 个主分区。

第一个扇区中的数据信息
Linux 就该这么学(RHEL7)
硬盘分区规划
Linux 就该这么学(RHEL7)

文件系统与数据资料

用户在硬件存储设备中执行的文件的建立、写入、读取、修改、转存与控制等操作都是依靠文件系统来完成的。文件系统的作用是合理规划硬盘,以保证用户正常的使用需求。Linux 系统支持数十种的文件系统,而最常见的文件系统如下:

  • Ext 3: 是一款日志文件系统,能够在系统异常宕机时避免文件系统资料丢失,并能自动修复数据的不一致与错误。然而,当硬盘容量较大时,所需的修复时间也会很长,而且也不能百分之百地保证资料不会丢失。它会把整个磁盘的每写入动作的细节都预先记录下来,以便在发生异常宕机后能回溯追踪到被中断的部分,然后尝试进行修改。
  • Ext 4: Ext 3 的改进版本,作为 RHEL 6 系统中的默认文件管理系统,它支持的存储容量高达 1 EB(1 EB=1073741824GB),且能够有无限多的子目录。另外,Ext 4 文件系统能够批量分配 block 块,从而极大地提高了读写效率。
  • XFS: 是一种高性能的日志文件系统,而且是 RHEL 7 中的默认的文件管理系统,它的优势在发生意外宕机后尤其明显,即可以快速地恢复可能被破坏的文件,而且强大的日志功能只用花费极低的计算和存储性能。并且它最大可支持的存储容量为 18EB,这几乎满足了所有需求。

Linux 系统中有一个名为 super block 的“硬盘地图”。Linux 系统并不是爸文件内容直接写入到这个“硬盘地图”里面,而是在里面记录着整个文件系统的信息。因为如果把所有文件都写入到这里面,它的体积将变得非常大,而且文件内容的查询与写入速度也会变得很慢。Linux 系统只是把每个文件的权限与属性记录在 inode 中,而且每个文件占用一个独立的 inode 表格,该表格的大小默认为 128 字节,里面记录的信息如下:

  • 该文件的访问权限(read、write、execute);
  • 该文件的所有者与所属组(owner、group);
  • 该文件的大小(size);
  • 该文件的创建或内容修改时间(ctime0);
  • 该文件的最后一次访问时间(atime);
  • 该文件的修改时间(mtime);
  • 文件的特殊权限(SUID、SGID、SBIT);
  • 该文件的真实数据地址(point)。

文件的实际内容则保存在 block 块中(大小可以是 1KB、2KB或4KB),一个 inode 的默认大小仅为 128KB(Ext3),记录一个 block 则消耗 4B。当文件的 inode 被写满后,Linux 系统会自动分配出一个 block 块,专门用于像 inode 那样记录其他 block 块的信息,这个把各个 block 块的内容串到一起,就能够让用户读到完整的文件内容了。对于存储文件内容的 block 块,有下面两种情况(以 4KB 的 block 大小为例进行说明)。

  • 情况一:文件很小(1KB),但依然会占用一个 block,因此会潜在浪费 3KB。
  • 情况二:文件很大(5KB),那么会占用两个 block(5KB-4KB 后剩下的 1KB 也要占用一个 block)。

计算机系统在发展过程中产生了众多的文件系统,为了使用户在读取或写入文件时不用关心底层的硬盘结构,Linux 内核中的软件层为用户程序提供了一个 VFS(Virtual File System,虚拟文件系统)接口,这样用户在操作文件时就是统一对这个虚拟文件系统进行操作。

<center>VFS的架构示意图</center>

Linux 就该这么学(RHEL7)

挂载硬件设备

mount 命令

mount 命令用于挂载文件系统。

格式: “mount 文件系统 挂载目录” 。

<center>mount 命令中的参数以及作用</center>

参数 作用
-a 挂载所有在/etc/fstab中定义的文件系统
-t 指定文件系统的类型

虽然使用 mount 命令挂载后就能使用文件系统,但系统在重启后挂载就会失效,即每次开机都要手动挂载一次。如果想要硬件设备和目录永久地进行自动关联,就必须把挂载信息按照指定填写格式 “设备文件 挂载目录 格式类型 权限选项 是否备份 是否自检” 写入到/etc/fstab文件中。

<center>用于挂载信息的指定填写格式中,各字段所表示的意义</center>

字段 意义
设备文件 一般为设备的路径 + 设备名称,也可以写唯一识别码(UUID,Universally Unique Identifier)
挂载目录 指定要挂载到的目录,需在挂载前创建好
格式类型 指定文件系统的格式,如 Ext3、Ext4、XFS、SWAP、iso9660(此为光盘设备)等
权限选项 若设置为 defaults,则默认权限为:rw,suid,dev,exec,auto,nouser,async
是否备份 若为 1 则开机后使用 dump 进行磁盘备份,为 0 则不备份
是否自检 若为 1 则开机后自动进行磁盘自检,为 0 则不自检

umount 命令

umount 命令用于撤销已经挂载的设备文件。

格式:“umount [挂载点/设备文件]”。

fdisk 命令

fdisk 命令用于管理磁盘分区,也是最常用的管理硬盘设备的命令,它提供了添加、删除、转换分区等功能。

格式:“fdisk [磁盘名称]”。

fdisk 命令中的参数以及作用
参数 作用
m 查看全部可用的参数
n 添加新的分区
d 删除某个分区信息
l 列出所有可用的分区类型
t 改变某个分区的类型
p 查看分区信息
w 保存并退出
q 不保存直接退出

例如,使用 fdisk 命令管理/dev/sdb硬盘设备:

[root@linuxprobe ~]# fdisk /dev/sdb
Welcome to fdisk (util-linux 2.23.2).

Changes will remain in memory only, until you decide to write them.
Be careful before using the write command.

Device does not contain a recognized partition table
Building a new DOS disklabel with disk identifier 0xb7026e44.

Command (m for help): p //查看硬盘设备已有的分区信息;

Disk /dev/sdb: 21.5 GB, 21474836480 bytes, 41943040 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk label type: dos
Disk identifier: 0xb7026e44

   Device Boot      Start         End      Blocks   Id  System

Command (m for help): n //添加新分区;
Partition type:
   p   primary (0 primary, 0 extended, 4 free)
   e   extended
Select (default p): p       //创建主分区;
Partition number (1-4, default 1): 1        //主分区编号范围是 1~4,默认输入 1 就可以;
First sector (2048-41943039, default 2048):         //此处敲回车(系统会自动计算出最靠前空闲扇区的位置);
Using default value 2048
Last sector, +sectors or +size{K,M,G} (2048-41943039, default 41943039): +2G        //创建出一个容量为 2G 的硬盘分区;
Partition 1 of type Linux and of size 2 GiB is set

Command (m for help): p //再次输入 p 参数查看硬盘设备中的分区信息;

Disk /dev/sdb: 21.5 GB, 21474836480 bytes, 41943040 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk label type: dos
Disk identifier: 0xb7026e44

   Device Boot      Start         End      Blocks   Id  System
/dev/sdb1            2048     4196351     2097152   83  Linux
//可以看到一个名为/dev/sdb1,起始扇区位置为 2048、结束扇区为 4196351 的主分区;
Command (m for help): w     //输入参数 w 回车,才能成功写入分区信息; 
The partition table has been altered!

Calling ioctl() to re-read partition table.
Syncing disks.

注意: 上述步骤执行完毕后,Linux 系统会自动把这个硬盘主分区抽象成/dev/sdb1 设备文件。可以使用file命令查看该文件的属性,但有些时候系统并没有自动把分区信息同步给Linux 内核,我们可以使用partprobe命令手动将分区信息同步到内核,而且一般推荐两次执行该命令。如果使用这个命令都无法解决问题,就重启计算机。

[root@linuxprobe ~]# file /dev/sdb1
/dev/sdb1: cannot open (No such file or directory)
[root@linuxprobe ~]# partprobe 
Warning: Unable to open /dev/sr0 read-write (Read-only file system).  /dev/sr0 has been opened read-only.
Warning: Unable to open /dev/sr0 read-write (Read-only file system).  /dev/sr0 has been opened read-only.
Warning: Unable to open /dev/sr0 read-write (Read-only file system).  /dev/sr0 has been opened read-only.
[root@linuxprobe ~]# file /dev/sdb1
/dev/sdb1: block special

格式化/dev/sdb1

[root@linuxprobe ~]# mkfs   //敲击两下回车补全会自有如下[root@linuxprobe ~]# partprobe 
Warning: Unable to open /dev/sr0 read-write (Read-only file system).  /dev/sr0 has been opened read-only.
Warning: Unable to open /dev/sr0 read-write (Read-only file system).  /dev/sr0 has been opened read-only.
Warning: Unable to open /dev/sr0 read-write (Read-only file system).  /dev/sr0 has been opened read-only.效果;
mkfs         mkfs.cramfs  mkfs.ext3    mkfs.fat     mkfs.msdos   mkfs.xfs     
mkfs.btrfs   mkfs.ext2    mkfs.ext4    mkfs.minix   mkfs.vfat  
[root@linuxprobe ~]# mkfs.xfs /dev/sdb1
meta-data=/dev/sdb1              isize=256    agcount=4, agsize=131072 blks
         =                       sectsz=512   attr=2, projid32bit=1
         =                       crc=0
data     =                       bsize=4096   blocks=524288, imaxpct=25
         =                       sunit=0      swidth=0 blks
naming   =version 2              bsize=4096   ascii-ci=0 ftype=0
log      =internal log           bsize=4096   blocks=2560, version=2
         =                       sectsz=512   sunit=0 blks, lazy-count=1
realtime =none                   extsz=4096   blocks=0, rtextents=0

挂载/dev/sdb1

[root@linuxprobe ~]# mkdir newFS    //创建挂载点目录;
[root@linuxprobe ~]# mount /dev/sdb1 newFS/ //将存储设备与挂载点目录关联;
[root@linuxprobe ~]# df -h  //查看挂载状态和硬盘使用量信息;
文件系统        容量  已用  可用 已用% 挂载点
/dev/sda3        97G  3.4G   94G    4% /
devtmpfs        2.0G     0  2.0G    0% /dev
tmpfs           2.0G   80K  2.0G    1% /dev/shm
tmpfs           2.0G  8.8M  2.0G    1% /run
tmpfs           2.0G     0  2.0G    0% /sys/fs/cgroup
/dev/sr0        3.5G  3.5G     0  100% /media/cdrom
/dev/sda1       997M  123M  875M   13% /boot
/dev/sdb1       2.0G   33M  2.0G    2% /root/newFS

du 命令

du 命令用于查看文件数据占用量,即用来查看一个或多个文件占用了多大的硬盘空间,du -sh /*可以统计根目录下所有一级目录占用了多大空间。

格式:“du [选项] [文件]”。

[root@linuxprobe ~]# cp -rf /etc/* newFS/
[root@linuxprobe ~]# ls newFS/
[root@linuxprobe ~]# du -sh newFS
34M newFS

创建自动挂载:

[root@linuxprobe ~]# vim /etc/fstab 
[root@linuxprobe ~]# tail -1 /etc/fstab 
/dev/sdb1   /newFS  xfs defaults    0   0

添加交换分区

SWAP (交换)分区是一种通过在硬盘预先一定的空间,然后把内存中暂时不常用额数据临时存放到硬盘中,以便腾出物理内存空间 让更活跃的程序服务来使用的技术,其设计的目的是为了解决真实物理内存不足的问题。但由于交换分区毕竟是通过硬盘设备读写数据的,速度肯定比不上物理内存,所以只有当真实的物理内存耗尽后才会调用交换分区的资源。

[root@linuxprobe ~]# fdisk /dev/sdb
Welcome to fdisk (util-linux 2.23.2).

Changes will remain in memory only, until you decide to write them.
Be careful before using the write command.

Command (m for help): n
Partition type:
   p   primary (1 primary, 0 extended, 3 free)
   e   extended
Select (default p): p
Partition number (2-4, default 2): 2
First sector (4196352-41943039, default 4196352): 
Using default value 4196352
Last sector, +sectors or +size{K,M,G} (4196352-41943039, default 41943039): +5G
Partition 2 of type Linux and of size 5 GiB is set

Command (m for help): p

Disk /dev/sdb: 21.5 GB, 21474836480 bytes, 41943040 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk label type: dos
Disk identifier: 0xb7026e44

   Device Boot      Start         End      Blocks   Id  System
/dev/sdb1            2048     4196351     2097152   83  Linux
/dev/sdb2         4196352    14682111     5242880   83  Linux

Command (m for help): w
The partition table has been altered!

Calling ioctl() to re-read partition table.

WARNING: Re-reading the partition table failed with error 16: Device or resource busy.
The kernel still uses the old table. The new table will be used at
the next reboot or after you run partprobe(8) or kpartx(8)
Syncing disks.
[root@linuxprobe ~]# partprobe  //保存完必须使用 partprobe 命令将分区信息写入到内存;
Warning: Unable to open /dev/sr0 read-write (Read-only file system).  /dev/sr0 has been opened read-only.
Warning: Unable to open /dev/sr0 read-write (Read-only file system).  /dev/sr0 has been opened read-only.
Warning: Unable to open /dev/sr0 read-write (Read-only file system).  /dev/sr0 has been opened read-only.

格式化交换分区:

[root@linuxprobe ~]# mkswap /dev/sdb2
Setting up swapspace version 1, size = 5242876 KiB
no label, UUID=e8869ee7-2142-4931-bb35-d19e41fb105f

增加交换分区大小:

[root@linuxprobe ~]# free -m        //查看交换分区大小(观察添加后的变化);
             total       used       free     shared    buffers     cached
Mem:          3939        644       3294          8          1        241
-/+ buffers/cache:        401       3537
Swap:         2047          0       2047
[root@linuxprobe ~]# swapon /dev/sdb2
[root@linuxprobe ~]# free -m         
             total       used       free     shared    buffers     cached
Mem:          3939        649       3289          8          1        241
-/+ buffers/cache:        406       3532
Swap:         7167          0       7167        //内存增加了 5G;

创建交换分区自动挂载

[root@linuxprobe ~]# vim /etc/fstab 
[root@linuxprobe ~]# tail -1 /etc/fstab 
/dev/sdb2   swap    swap    defaults    0   0   

磁盘容量配额

磁盘容量配额服务是用来限制某位用户或某个用户针对特定文件夹可以使用的最大磁盘空间或最大文件个数,一旦达到了这个最大值就不再允许继续使用。可以使用quota命令进行磁盘容量配额管理,quota命令还有软限制和硬限制的功能。

  • 软限制: 当达到软限制时会提示用户,但仍允许用户在限定的额度内继续使用。
  • 硬限制: 当达到硬限制时会提示用户,且强制终止用户的操作。

RHEL 7系统已经安装了 quota 磁盘容量配额服务程序包,但存储设备却默认没有开启对 quota 的支持,此时需要手动编辑配置文件,让 RHEL 7 系统中的/boot目录能够支持 quota 磁盘配额技术。RHEL 6 系统使用的磁盘容量配额服务,使用的是 usrquota参数,而 RHEL 7 系统使用的则是uquota参数。


[root@linuxprobe ~]# vim /etc/fstab 
[root@linuxprobe ~]# cat /etc/fstab 

#

/etc/fstab

Created by anaconda on Tue May 21 18:42:59 2019

#

Accessible filesystems, by reference, are maintained under '/dev/disk'

See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info

#
UUID=35934334-2a09-4e25-8785-49f4bb930ab0 / xfs defaults 1 1
UUID=a9720080-82d2-4fd9-834d-2b8840238f5d /boot xfs defaults,uquota //添加 uquota 参数 1 2
UUID=08f48ca4-0a18-4cf8-83f3-693742a47527 swap swap defaults 0 0

/dev/cdrom /media/cdrom iso9660 defaults 0 0

/dev/sdb1 /newFS xfs defaults 0 0
/dev/sdb2 swap swap defaults 0 0

[root@linuxprobe ~]# reboot
[root@linuxprobe ~]# mount |grep boot
/dev/sda1 on /boot type xfs (rw,relatime,seclabel,attr2,inode64,usrquota) //重启完再次查看,可以看到 usrquota 参数

**创建用于检查磁盘配额效果的用户 tom,并针对`/boot`目录增加其他人的写如权限,保证用户能够正常写入数据:**

[root@linuxprobe ~]# useradd tom
[root@linuxprobe ~]# chmod o+w /boot

## xfs_quota 命令
>xfs_quota 命令是一个专门针对 XFS 系统来管理 quota 磁盘容量配额服务而设计的命令。其中 `-c`参数用于以参数的形式设置要执行的命令;`-x`参数是专家模式,让运维人员能够对 quota 服务进行更多复杂的配置。

**格式:**“xfs_quota [参数] 配额  文件系统”。

**使用xfs_quota 命令来设置用户 tom 对 `/boot`目录的 quota 磁盘容量配额,磁盘使用量的软限制和硬限制分别为 3MB 和 6MB;创建文件数量的软限制和硬限制分别为 3 个和 6 个:**

[root@linuxprobe ~]# xfs_quota -x -c 'limit bsoft=3m bhard=6m isoft=3 ihard=6 tom' /boot
[root@linuxprobe ~]# xfs_quota -x -c report /boot
User quota on /boot (/dev/sda1)
Blocks
User ID Used Soft Hard Warn/Grace


root 92376 0 0 00 [--------]
tom 0 3072 6144 00 [--------]

[root@linuxprobe ~]# su - tom
[tom@linuxprobe ~]$ dd if=/dev/zero of=/boot/tom bs=5M count=1
1+0 records in
1+0 records out
5242880 bytes (5.2 MB) copied, 0.00360838 s, 1.5 GB/s
[root@linuxprobe ~]# xfs_quota -x -c report /boot
User quota on /boot (/dev/sda1)
Blocks
User ID Used Soft Hard Warn/Grace


root 92376 0 0 00 [--------]
tom 5120 3072 6144 00 [7 days]

[tom@linuxprobe ~]$ dd if=/dev/zero of=/boot/tom bs=8M count=1
dd: error writing ‘/boot/tom’: Disk quota exceeded
1+0 records in
0+0 records out
6291456 bytes (6.3 MB) copied, 0.00655487 s, 960 MB/s

[root@linuxprobe ~]# xfs_quota -x -c report /boot
User quota on /boot (/dev/sda1)
Blocks
User ID Used Soft Hard Warn/Grace


root 92376 0 0 00 [--------]
tom 6144 3072 6144 00 [7 days]

## edquota 命令
>edquota 命令用于编辑用户的 quota 配额限制。在为用户设置了 quota 磁盘容量配额限制后,可以使用 edquota 命令按需修改限额的数值。其中,`-u`参数表示要针对哪个用户进行设置;`-g`参数表示要针对哪个用户组进行设置。edquota 命令会调用 vi 或 vim 编辑器来让 root 管理员来修改要限制的具体细节。

**格式:**“edquota [参数] [用户]”。

**把 tom 用户的硬盘使用量的硬限额从 5MB 提升到 8MB:**

[root@linuxprobe ~]# edquota -u tom
Disk quotas for user tom (uid 1001):
Filesystem blocks soft hard inodes soft hard
/dev/sda1 6144 3072 8192 //提升到8G; 1 3 6
[root@linuxprobe ~]# su - tom //切换到 tom 用户;
Last login: Wed Jun 12 10:18:53 EDT 2019 on pts/0
[tom@linuxprobe ~]$ dd if=/dev/zero of=/boot/tom bs=8M count=1
1+0 records in
1+0 records out
8388608 bytes (8.4 MB) copied, 0.0134939 s, 622 MB/s
[root@linuxprobe ~]# xfs_quota -x -c report /boot
User quota on /boot (/dev/sda1)
Blocks
User ID Used Soft Hard Warn/Grace


root 92376 0 0 00 [--------]
tom 8192 3072 8192 00 [6 days]
[tom@linuxprobe ~]$ dd if=/dev/zero of=/boot/tom bs=10M count=1
dd: error writing ‘/boot/tom’: Disk quota exceeded
1+0 records in
0+0 records out
8388608 bytes (8.4 MB) copied, 0.0214434 s, 391 MB/s

# 软硬方式链接
**Linux 系统中软链接和硬链接**
* **硬链接:** 可以理解为一个“指向原始文件的 inode 的指针”,系统不为它分配独立的 inode 和文件。所以,硬链接文件和原始文件其实是同一个文件,只是名字不同。我们每添加一个硬链接,该文件的 inode 连接数就会增加 1;而且只有当该文件的 inode 连接数为 0 时,才算彻底将它删除。即由于硬链接实际上是指向原文件的 inode 的指针,因此即便原始文件被删除,依然可以通过硬链接文件来访问。但由于技术局限性,不能跨分区对目录文件进行链接。
* **软链接(也称为斧蛤链接[symbolic link]):** 仅仅包含所链接文件的路径名,因此能链接目录文件,也可以跨越文件系统进行链接。但是,当原始文件被删除后,链接文件也将失效,跟 Windows 系统的“快捷方式”具有一样的性质。

## ln 命令
>ln 命令用于创建链接文件。

**格式:** “ln [选项] 目标”。

<center>ln 命令中可用的参数以及作用</center>

|参数|用|
|--|--|
|`-s`|创建"符号链接"(如果不带-`s`参数,则默认创建硬链接)|
|`-f`|强制创建文件或目录的链接|
|`-i`|覆盖前先询问|
|`-v`|显示创建链接的过程|
**例如:**

[root@linuxprobe ~]# echo "welcome to linuxprobe.com" >readme.txt
[root@linuxprobe ~]# ln -s readme.txt read.txt
[root@linuxprobe ~]# cat readme.txt
welcome to linuxprobe.com
[root@linuxprobe ~]# cat read.txt
welcome to linuxprobe.com
[root@linuxprobe ~]# rm -f readme.txt
[root@linuxprobe ~]# cat read.txt
cat: read.txt: No such file or directory

# RAID 与 LVM 磁盘阵列技术
## RAID(独立冗余磁盘阵列)
>RAID 技术通过把多个硬盘设备组合成一个容量更大、安全性更好的磁盘阵列,并把数据切割成多个区段后分别存放在各个不同的物理磁盘设备上,然后利用分散读写技术来提升磁盘阵列整体性能,同时把多个重要数据的副本同步到不同的物理硬盘设备上,从而起到了冗余备份效果。

## RAID 0
>RAID 0 技术把多块物理硬盘设备(至少两块)通过硬件或软件的方式串联在一起,组成一个大的卷组,并把数据一次写入到各个物理磁盘中。这样在理想状态下,硬盘设备的读写性能会提升数倍,但若任意一块硬盘发生故障将导致整个系统的数据都受到破坏。通俗来讲,RAID 0 技术能够有效地提升硬盘数据的吞吐速度,但是不具备数据备份和错误修复能力。

<center>RAID 0 技术示意图</center>

![](https://s2.ax1x.com/2019/06/13/Vho0k4.png)

## RAID 1
>RAID 1 是把两块以上的硬盘设备进行绑定,在写入数据时,是将数据同时写入到多个硬盘设备上(可以将其视为数据的镜像或备份)。当其中某一块硬盘发生故障后,一般会立即自动以热交换的方式来恢复数据的正常使用。
<center>RAID 1 技术示意图</center>

![](https://s2.ax1x.com/2019/06/13/VhT8ED.png)
## RAID 5
>RAID 5 技术是把硬盘设备的数据奇偶校验信息保存到其他硬盘设备中。RAID 5 磁盘阵列组中数据的奇偶校验信息并不是单独保存到某一块硬盘设备中,而是存储到除自身以外的其他每一块硬盘设备上,这样的好处是其中任何一块设备损坏后不至于出现致命缺陷。
<center>RAID 5 技术示意图</center>

![](https://s2.ax1x.com/2019/06/13/VhTUgI.png)
>即 RAID 5 技术实际上没有备份硬盘中的真实数据信息,而是当硬盘设备出现问题后通过奇偶校验信息来尝试重建损坏的数据。

## RAID 10
>RAID 10 技术是 RAID 1 +  RAID 0 技术的一个“组合体”。RAID 10 技术需要至少 4 块硬盘来组件,其中先分别两两制作成  RAID 1 磁盘阵列,以保证数据的安全性;然后再对两个 RAID 1 磁盘阵列实施 RAID 0 技术,进一步提高硬盘设备的读写速度。这样一来,只要坏的不是同一组中的所有硬盘,那么最多可以损坏 50% 的硬盘设备而不丢失数据。由于 RAID 10 技术继承了 RAID 0 的高读写速度和 RAID  1 的数据安全性,在不考虑成本的情况下,RAID 10 的性能超过了 RAID 5,因此 RAID 10 是当前广泛使用的一种存储技术。

<center>RAID 10 技术示意图</center>

![](https://s2.ax1x.com/2019/06/13/Vh7vSs.png)
## 部署磁盘阵列
## mdadm 命令
>mdadm 命令用于管理 Linux 系统中的软件 RAID 磁盘阵列。

**格式:** “mdadm [模式]<RAID设备名称>[选项] [成员设备名称]”。
<center>mdadm 命令的常用参数和作用</center>

|参数|作用|
|--|--|
|`-a`|检测设备名称|
|`-n`|指定设备数量|
|`-l`|指定 RAID 级别|
|`-C`|创建|
|`-v`|显示过程|
|`-f`|模拟设备损坏|
|`-r`|移除设备|
|`-Q`|查看摘要信息|
|`-D`|查看详细信息|
|`-S`|停止 RAID 磁盘阵列|
**实验:使用 mdadm 命令创建 RAID 10**
>其中,`-C`参数代表创建一个 RAID 阵列卡;`-v`参数是显示创建过程;设备名称为:/dev/md0;`-a yes`参数代表自动创建设备文件;`-n 4`代表使用 4 块硬盘来部署这个 RAID 磁盘阵列;`-l 10`参数表示使用 RAID 10 方案;最后加上4 块硬盘设备的名称。

**第 1 步:** 使用 `mdadm`命令创建 RAID 10,名称为:`/dev/md0`

[root@linuxprobe ~]# ls /dev/sd*
/dev/sda /dev/sda1 /dev/sda2 /dev/sda3 /dev/sdb /dev/sdc /dev/sdd /dev/sde
[root@linuxprobe ~]# mdadm -Cv /dev/md0 -a yes -n 4 -l 10 /dev/sdb /dev/sdc /dev/sdd /dev/sde
mdadm: layout defaults to n2
mdadm: layout defaults to n2
mdadm: chunk size defaults to 512K
mdadm: size set to 20954624K
mdadm: Defaulting to version 1.2 metadata
mdadm: array /dev/md0 started.

**第 2 步:** 格式化 RAID 磁盘阵列为`ext4 格式`

[root@linuxprobe ~]# mkfs.ext4 /dev/md0
mke2fs 1.42.9 (28-Dec-2013)
Filesystem label=
OS type: Linux
Block size=4096 (log=2)
Fragment size=4096 (log=2)
Stride=128 blocks, Stripe width=256 blocks
2621440 inodes, 10477312 blocks
523865 blocks (5.00%) reserved for the super user
First data block=0
Maximum filesystem blocks=2157969408
320 block groups
32768 blocks per group, 32768 fragments per group
8192 inodes per group
Superblock backups stored on blocks:
32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632, 2654208,
4096000, 7962624

Allocating group tables: done
Writing inode tables: done
Creating journal (32768 blocks): done
Writing superblocks and filesystem accounting information: done

**第 3 步:** 创建挂载点并挂载硬盘设备

[root@linuxprobe ~]# mkdir /raid
[root@linuxprobe ~]# mount /dev/md0 /raid/
[root@linuxprobe ~]# df -h
Filesystem Size Used Avail Use% Mounted on
/dev/sda3 97G 3.2G 94G 4% /
devtmpfs 2.0G 0 2.0G 0% /dev
tmpfs 2.0G 80K 2.0G 1% /dev/shm
tmpfs 2.0G 8.8M 2.0G 1% /run
tmpfs 2.0G 0 2.0G 0% /sys/fs/cgroup
/dev/sda1 997M 123M 875M 13% /boot
/dev/md0 40G 49M 38G 1% /raid //挂载成功后可以看到可用空间为 40 GB;

**第 4 步:** 查看/dev/md0磁盘阵列详细信息,并把挂载信息写入到配置文件中

[root@linuxprobe ~]# mdadm -D /dev/md0
/dev/md0:
Version : 1.2
Creation Time : Fri Jun 14 10:20:01 2019
Raid Level : raid10
Array Size : 41909248 (39.97 GiB 42.92 GB)
Used Dev Size : 20954624 (19.98 GiB 21.46 GB)
Raid Devices : 4
Total Devices : 4
Persistence : Superblock is persistent

Update Time : Fri Jun 14 10:30:57 2019
      State : clean 

Active Devices : 4
Working Devices : 4
Failed Devices : 0
Spare Devices : 0

     Layout : near=2
 Chunk Size : 512K

       Name : linuxprobe.com:0  (local to host linuxprobe.com)
       UUID : c9995353:a631a2f8:08127815:afa346f6
     Events : 17

Number   Major   Minor   RaidDevice State
   0       8       16        0      active sync   /dev/sdb
   1       8       32        1      active sync   /dev/sdc
   2       8       48        2      active sync   /dev/sdd
   3       8       64        3      active sync   /dev/sde

[root@linuxprobe ~]# echo "/dev/md0 /raid ext4 defaults 0 0" >>/etc/fstab

## 损坏磁盘阵列及修复
**确认有损坏的硬盘,使用 mdadm 命令中的 `-f
`参数将设备移除(此时并不影响挂载目录/raid 的正常使用):**

[root@linuxprobe ~]# mdadm -f /dev/md0 /dev/sdb //模拟设备 /dev/sdb 损坏
mdadm: set /dev/sdb faulty in /dev/md0
[root@linuxprobe ~]# mdadm -D /dev/md0
/dev/md0:
Version : 1.2
Creation Time : Fri Jun 14 21:36:17 2019
Raid Level : raid10
Array Size : 41909248 (39.97 GiB 42.92 GB)
Used Dev Size : 20954624 (19.98 GiB 21.46 GB)
Raid Devices : 4
Total Devices : 4
Persistence : Superblock is persistent

Update Time : Fri Jun 14 21:56:08 2019
      State : clean, degraded 

Active Devices : 3
Working Devices : 3
Failed Devices : 1
Spare Devices : 0

     Layout : near=2
 Chunk Size : 512K

       Name : linuxprobe.com:0  (local to host linuxprobe.com)
       UUID : 605a8bcc:2c216650:29bbc074:87f4c958
     Events : 21

Number   Major   Minor   RaidDevice State
   0       0        0        0      removed
   1       8       32        1      active sync   /dev/sdc
   2       8       48        2      active sync   /dev/sdd
   3       8       64        3      active sync   /dev/sde

   0       8       16        -      faulty   /dev/sdb   
**由于是在虚拟机模拟,需要重启,然后再使用 mdadm 命令添加新设备到磁盘阵列中即可:**

[root@linuxprobe ~]# reboot
[root@linuxprobe ~]# umount /raid
[root@linuxprobe ~]# mdadm /dev/md0 -a /dev/sdb
mdadm: added /dev/sdb
[root@linuxprobe ~]# mount -a
[root@linuxprobe ~]# df -h
Filesystem Size Used Avail Use% Mounted on
/dev/sda3 97G 3.2G 94G 4% /
devtmpfs 2.0G 0 2.0G 0% /dev
tmpfs 2.0G 80K 2.0G 1% /dev/shm
tmpfs 2.0G 8.8M 2.0G 1% /run
tmpfs 2.0G 0 2.0G 0% /sys/fs/cgroup
/dev/sda1 997M 123M 875M 13% /boot
/dev/md0 40G 49M 38G 1% /raid

## 磁盘阵列+备份盘
>RAID 10 磁盘阵列中最多允许 50% 的硬盘设备发生故障,但存在一种极端情况是,即同一 RAID 1 磁盘阵列中的设备若全部损坏,也会导致数据丢失。所以,这时可以使用 RAID 备份盘技术来预防这类事故。该技术的核心是准备一块足够大的硬盘,这块硬盘平时处于闲置状态,一旦 RAID 磁盘阵列中有硬盘出现故障后会马上自动顶替上去。

**实验:部署 RAID 5 + 备份盘**
>参数`-n 3`代表创建这个 RAID 5 磁盘阵列需要 3 块硬盘,参数`-l 5`代表 RAID 的级别,参数`-x`代表一块备份盘。

 
**第 1 步:** 创建磁盘阵列 RAID 5,名称为 md0。

[root@linuxprobe ~]# mdadm -Cv /dev/md0 -n 3 -l 5 -x 1 /dev/sd[b,c,d,e]
mdadm: layout defaults to left-symmetric
mdadm: layout defaults to left-symmetric
mdadm: chunk size defaults to 512K
mdadm: size set to 20954624K
mdadm: Defaulting to version 1.2 metadata
mdadm: array /dev/md0 started.

**第 2 步:** 查看磁盘阵列详细信息了;

[root@linuxprobe ~]# mdadm -D /dev/md0
/dev/md0:
Version : 1.2
Creation Time : Sun Jun 16 01:16:34 2019
Raid Level : raid5
Array Size : 41909248 (39.97 GiB 42.92 GB)
Used Dev Size : 20954624 (19.98 GiB 21.46 GB)
Raid Devices : 3
Total Devices : 4
Persistence : Superblock is persistent

Update Time : Sun Jun 16 01:16:55 2019
      State : clean, degraded, recovering 

Active Devices : 2
Working Devices : 4
Failed Devices : 0
Spare Devices : 2

     Layout : left-symmetric
 Chunk Size : 512K

Rebuild Status : 18% complete

       Name : linuxprobe.com:0  (local to host linuxprobe.com)
       UUID : e609cdb3:9c22f2f2:ecf6d77a:20031cc8
     Events : 4

Number   Major   Minor   RaidDevice State
   0       8       16        0      active sync   /dev/sdb
   1       8       32        1      active sync   /dev/sdc
   4       8       48        2      spare rebuilding   /dev/sdd`#未激活状态,等一会就会变成激活状态(active sync);
   3       8       64        -      spare   /dev/sde
**第 3 步:** 格式化磁盘阵列为 ext4 格式;

[root@linuxprobe ~]# mkfs.ext4 /dev/md0
mke2fs 1.42.9 (28-Dec-2013)
Filesystem label=
OS type: Linux
Block size=4096 (log=2)
Fragment size=4096 (log=2)
Stride=128 blocks, Stripe width=256 blocks
2621440 inodes, 10477312 blocks
523865 blocks (5.00%) reserved for the super user
First data block=0
Maximum filesystem blocks=2157969408
320 block groups
32768 blocks per group, 32768 fragments per group
8192 inodes per group
Superblock backups stored on blocks:
32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632, 2654208,
4096000, 7962624

Allocating group tables: done
Writing inode tables: done
Creating journal (32768 blocks): done
Writing superblocks and filesystem accounting information: done

**第 4 步:** 创建挂载点并挂载;

[root@linuxprobe ~]# mkdir /raid
[root@linuxprobe ~]# echo "/dev/md0 /raid ext4 defaults 0 0" >>/etc/fstab
[root@linuxprobe ~]# mount -a
[root@linuxprobe ~]# df -h
Filesystem Size Used Avail Use% Mounted on
/dev/sda3 97G 3.2G 94G 4% /
devtmpfs 2.0G 0 2.0G 0% /dev
tmpfs 2.0G 80K 2.0G 1% /dev/shm
tmpfs 2.0G 8.8M 2.0G 1% /run
tmpfs 2.0G 0 2.0G 0% /sys/fs/cgroup
/dev/sda1 997M 123M 875M 13% /boot
/dev/md0 40G 49M 38G 1% /raid

**第 5 步:** 测试。模拟磁盘设备/dev/sdb故障,马上观察备用盘会不会自动顶替上来;

[root@linuxprobe ~]# mdadm /dev/md0 -f /dev/sdb
mdadm: set /dev/sdb faulty in /dev/md0
[root@linuxprobe ~]# mdadm -D /dev/md0
/dev/md0:
Version : 1.2
Creation Time : Sun Jun 16 01:16:34 2019
Raid Level : raid5
Array Size : 41909248 (39.97 GiB 42.92 GB)
Used Dev Size : 20954624 (19.98 GiB 21.46 GB)
Raid Devices : 3
Total Devices : 4
Persistence : Superblock is persistent

Update Time : Sun Jun 16 01:37:50 2019
      State : clean, degraded, recovering 

Active Devices : 2
Working Devices : 3
Failed Devices : 1
Spare Devices : 1

     Layout : left-symmetric
 Chunk Size : 512K

Rebuild Status : 0% complete

       Name : linuxprobe.com:0  (local to host linuxprobe.com)
       UUID : e609cdb3:9c22f2f2:ecf6d77a:20031cc8
     Events : 22

Number   Major   Minor   RaidDevice State
   3       8       64        0      spare rebuilding   /dev/sde
   1       8       32        1      active sync   /dev/sdc
   4       8       48        2      active sync   /dev/sdd

   0       8       16        -      faulty   /dev/sdb
# LVM(逻辑卷管理器)
>在硬盘分好区或者部署为 RAID 磁盘阵列之后,再想修改硬盘分区大小就不容易了,即当用户想要随着实际需求的变化调整硬盘分区大小时,会受到硬盘“灵活性”的限制,这时就需要一只狗非常普及的硬盘设备资源管理技术- ->LVM(逻辑卷管理器)。
>逻辑卷管理器是 Linux 系统用于对硬盘分区进行管理的一种机制,其创建初衷是为了解决硬盘设备在创建分区后不易修改分区大小的缺陷。尽管对传统的硬盘分区进行强制扩容或缩容从理论上来讲是可行的,但是却可能造成数据的丢失。而 LVM 技术是在硬盘分区和文件系统之间添加一个逻辑层,它提供一个抽象的卷组,可以把多块硬盘进行卷组合并,这样一来,用户就不必关心物理硬盘设备的底层架构和布局,就可以实现对硬盘分区的动态调整。

<center>逻辑卷管理器的技术结构</center>

![](https://s2.ax1x.com/2019/06/16/VTOtXD.png)
## 部署逻辑卷
<center>常用的 LVM 部署命令</certer>

|功能/命令|物理卷管理|卷组管理|逻辑卷管理|
|--|--|--|--|
|扫描|`pvscan`|`vgscan`|`lvscan`|
|建立|`pvcreate`|`vgcreate`|`lvcreate`|
|显示|`pvdisplay`|`vgdisplay`|`lvdisplay`|
|删除|`pvremove`|`vgremove`|`lvremove`|
|扩展||`vgextend`|`lvextend`|
|缩小||`vgreduce`|`lvreduce`|

**实验:LVM 实验**

**第 1 步:** 让新添加的2块硬盘设备支持 LVM 技术。

[root@linuxprobe ~]# ls /dev/sd*
/dev/sda /dev/sda1 /dev/sda2 /dev/sda3 /dev/sdb /dev/sdc
[root@linuxprobe ~]# pvcreate /dev/sdb /dev/sdc
Physical volume "/dev/sdb" successfully created
Physical volume "/dev/sdc" successfully created
[root@linuxprobe ~]# vgcreate storage /dev/sd[b,c]
Volume group "storage" successfully created
[root@linuxprobe ~]# vgdisplay
--- Volume group ---
VG Name storage
System ID
Format lvm2
Metadata Areas 2
Metadata Sequence No 1
VG Access read/write
VG Status resizable
MAX LV 0
Cur LV 0
Open LV 0
Max PV 0
Cur PV 2
Act PV 2
VG Size 39.99 GiB
PE Size 4.00 MiB
Total PE 10238
Alloc PE / Size 0 / 0
Free PE / Size 10238 / 39.99 GiB
VG UUID DDalCX-EcFM-1QoZ-mrni-mK0d-tTgo-clNTv4

**第 2 步:** 切割出一个约为 150M 的逻辑卷设备。
>**注意:** 在对逻辑卷进行切割时有两种计量单位。一种是以容量为单位,使用的参数为`-L`。例如,使用`-L 150M`的逻辑卷。另外一种是以基本单位的个数为单位,使用的参数为`-l`,每个基本单位默认为 4M。例如,使用`-l 37`可以生成一个大小为`37*4M=148MB`的逻辑卷。

[root@linuxprobe ~]# lvcreate -n vo -l 37 storage
Logical volume "vo" created
[root@linuxprobe ~]# lvdisplay
--- Logical volume ---
LV Path /dev/storage/vo
LV Name vo
VG Name storage
LV UUID TiqS10-mqkx-zMor-KGPP-au4g-6T0B-1BkvMm
LV Write Access read/write
LV Creation host, time linuxprobe.com, 2019-06-16 06:32:57 -0400
LV Status available

open 0

LV Size 148.00 MiB
Current LE 37
Segments 1
Allocation inherit
Read ahead sectors auto

  • currently set to 8192
    Block device 253:0
    **第 3 步:** 格式化生成好的逻辑卷。
    >Linux 系统会把 LVM 中的逻辑卷设备存放在/dev设备中(实际上是做了一个符号链接),同时会以卷组的名称来建立一个目录,其中保存了逻辑卷的设备映射文件(即/dev/卷组名称/逻辑卷名称)。

    [root@linuxprobe ~]# mkfs.ext4 /dev/storage/vo
    mke2fs 1.42.9 (28-Dec-2013)
    Filesystem label=
    OS type: Linux
    Block size=1024 (log=0)
    Fragment size=1024 (log=0)
    Stride=0 blocks, Stripe width=0 blocks
    38000 inodes, 151552 blocks
    7577 blocks (5.00%) reserved for the super user
    First data block=1
    Maximum filesystem blocks=33816576
    19 block groups
    8192 blocks per group, 8192 fragments per group
    2000 inodes per group
    Superblock backups stored on blocks:
    8193, 24577, 40961, 57345, 73729

Allocating group tables: done
Writing inode tables: done
Creating journal (4096 blocks): done
Writing superblocks and filesystem accounting information: done

**第 4 步:** 创建挂载点并挂载使用。

[root@linuxprobe ~]# mkdir /vo
[root@linuxprobe ~]# echo "/dev/storage/vo /vo ext4 defaults 0 0">> /etc/fstab
[root@linuxprobe ~]# mount -a
[root@linuxprobe ~]# df -h
Filesystem Size Used Avail Use% Mounted on
/dev/sda3 97G 3.2G 94G 4% /
devtmpfs 2.0G 0 2.0G 0% /dev
tmpfs 2.0G 80K 2.0G 1% /dev/shm
tmpfs 2.0G 8.8M 2.0G 1% /run
tmpfs 2.0G 0 2.0G 0% /sys/fs/cgroup
/dev/sda1 997M 123M 875M 13% /boot
/dev/mapper/storage-vo 140M 1.6M 128M 2% /vo

## 扩容逻辑卷
**第 1 步:** 将逻辑卷 vo 扩容至 300M;

[root@linuxprobe ~]# umount /vo # 扩容前先卸载设备与挂载点关联;
[root@linuxprobe ~]# df -h
Filesystem Size Used Avail Use% Mounted on
/dev/sda3 97G 3.2G 94G 4% /
devtmpfs 2.0G 0 2.0G 0% /dev
tmpfs 2.0G 80K 2.0G 1% /dev/shm
tmpfs 2.0G 8.8M 2.0G 1% /run
tmpfs 2.0G 0 2.0G 0% /sys/fs/cgroup
/dev/sda1 997M 123M 875M 13% /boot
[root@linuxprobe ~]# lvextend -L 300M /dev/storage/vo
Extending logical volume vo to 300.00 MiB
Logical volume vo successfully resized

**第 2 步:** 检查硬盘完整性。

[root@linuxprobe ~]# e2fsck -f /dev/storage/vo
e2fsck 1.42.9 (28-Dec-2013)
Pass 1: Checking inodes, blocks, and sizes
Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
/dev/storage/vo: 11/38000 files (0.0% non-contiguous), 10453/151552 blocks

**第 3 步:** 重置硬盘容量。

[root@linuxprobe ~]# resize2fs /dev/storage/vo
resize2fs 1.42.9 (28-Dec-2013)
Resizing the filesystem on /dev/storage/vo to 307200 (1k) blocks.
The filesystem on /dev/storage/vo is now 307200 blocks long.

**第 4 步:** 重新挂载硬盘并查看挂载状态。

[root@linuxprobe ~]# mount -a
[root@linuxprobe ~]# df -h
Filesystem Size Used Avail Use% Mounted on
/dev/sda3 97G 3.2G 94G 4% /
devtmpfs 2.0G 0 2.0G 0% /dev
tmpfs 2.0G 80K 2.0G 1% /dev/shm
tmpfs 2.0G 8.8M 2.0G 1% /run
tmpfs 2.0G 0 2.0G 0% /sys/fs/cgroup
/dev/sda1 997M 123M 875M 13% /boot
/dev/mapper/storage-vo 287M 2.1M 266M 1% /vo

## 缩小逻辑卷
>相较于扩容逻辑卷,在对逻辑卷进行缩容操作时,其丢失数据的风险更大。所以在生产环境中执行相应操作时,一定要提前备份好数据。另外 Linux 系统规定,在对 LVM 逻辑卷进行缩容操作之前,要先检查文件系统的完整性(也是为了保证我们的数据安全)。

**第 1 步:** 检查文件系统的完整性。

[root@linuxprobe ~]# umount /vo
[root@linuxprobe ~]# e2fsck -f /dev/storage/vo
e2fsck 1.42.9 (28-Dec-2013)
Pass 1: Checking inodes, blocks, and sizes
Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
/dev/storage/vo: 11/76000 files (0.0% non-contiguous), 15759/307200 blocks

**第 2 步:** 把逻辑卷 vo 容量减少到 120M。

[root@linuxprobe ~]# resize2fs /dev/storage/vo 120M
resize2fs 1.42.9 (28-Dec-2013)
Resizing the filesystem on /dev/storage/vo to 122880 (1k) blocks.
The filesystem on /dev/storage/vo is now 122880 blocks long.

[root@linuxprobe ~]# lvreduce -L 120M /dev/storage/vo
WARNING: Reducing active logical volume to 120.00 MiB
THIS MAY DESTROY YOUR DATA (filesystem etc.)
Do you really want to reduce vo? [y/n]: y
Reducing logical volume vo to 120.00 MiB
Logical volume vo successfully resized

**第 3 步:** 重新挂载文件系统并检查系统状态。

[root@linuxprobe ~]# mount -a
[root@linuxprobe ~]# df -h
Filesystem Size Used Avail Use% Mounted on
/dev/sda3 97G 3.2G 94G 4% /
devtmpfs 2.0G 0 2.0G 0% /dev
tmpfs 2.0G 80K 2.0G 1% /dev/shm
tmpfs 2.0G 8.8M 2.0G 1% /run
tmpfs 2.0G 0 2.0G 0% /sys/fs/cgroup
/dev/sda1 997M 123M 875M 13% /boot
/dev/mapper/storage-vo 113M 1.6M 103M 2% /vo

## 逻辑卷快照
>LVM 还具备有“快照卷”功能,该功能类似于虚拟机软件的还原时间点功能,例如,可以对某一个逻辑卷设备做一次快照,日后发现数据被改错了,就可以利用之前做好的快炸卷进行覆盖还原。

**LVM 快照卷功能具有两个特点:**
* 快照卷的容量必须等同于逻辑卷的容量;
* 快照卷仅一次有效,一旦执行还原操作后则会会立即自动删除。

**逻辑卷快照实验**

**第 1 步:** 查看卷组信息。

[root@linuxprobe ~]# vgdisplay
--- Volume group ---
VG Name storage
System ID
Format lvm2
Metadata Areas 2
Metadata Sequence No 6
VG Access read/write
VG Status resizable
MAX LV 0
Cur LV 1
Open LV 1
Max PV 0
Cur PV 2
Act PV 2
VG Size 39.99 GiB
PE Size 4.00 MiB
Total PE 10238
Alloc PE / Size 30 / 120.00 MiB #已使用 120M;
Free PE / Size 10208 / 39.88 GiB #空闲容量还有 39.88GB;
VG UUID 102FQs-pbKK-lIAC-hF7b-XncB-CwCi-6j1lWu

**第 2 步:** 向逻辑卷设备所挂载的目录写入一个测试文件。

[root@linuxprobe ~]# echo "test" >>/vo/test.txt
[root@linuxprobe ~]# ls -l /vo
total 14
drwx------. 2 root root 12288 Jun 17 21:58 lost+found
-rw-r--r--. 1 root root 5 Jun 17 22:11 test.txt

**第 3 步:** 使用`-s`参数生成一个快照卷,使用`-L`参数指定切割大小,`-n`参数指定名称,另外还需要在后面指定针对哪个逻辑卷执行的快照操作。

[root@linuxprobe ~]# lvcreate -L 120M -s -n SNAP /dev/storage/vo
Logical volume "SNAP" created

[root@linuxprobe ~]# lvdisplay
--- Logical volume ---
LV Path /dev/storage/vo #逻辑卷路径;
LV Name vo
VG Name storage #卷组名称;
LV UUID MsMB2G-FHiP-Jy61-8pf6-HYKv-pn7A-gg9Jv7
LV Write Access read/write
LV Creation host, time linuxprobe.com, 2019-06-17 21:56:38 -0400
LV snapshot status source of
SNAP [active]
LV Status available

open 1

LV Size 120.00 MiB
Current LE 30
Segments 1
Allocation inherit
Read ahead sectors auto

  • currently set to 8192
    Block device 253:0

    --- Logical volume ---
    LV Path /dev/storage/SNAP
    LV Name SNAP
    VG Name storage
    LV UUID ICNPSs-Ey69-H1lf-djyZ-xqhD-J78F-vaqrzq
    LV Write Access read/write
    LV Creation host, time linuxprobe.com, 2019-06-17 22:14:16 -0400
    LV snapshot status active destination for vo #快照卷信息;
    LV Status available

    open 0

    LV Size 120.00 MiB
    Current LE 30
    COW-table size 120.00 MiB
    COW-table LE 30
    Allocated to snapshot 0.01% #快照卷存储占用量状态;
    Snapshot chunk size 4.00 KiB
    Segments 1
    Allocation inherit
    Read ahead sectors auto

  • currently set to 8192
    Block device 253:1
    **第 4 步:** 创建一个 100M 的垃圾文件,观察快照卷状态。

    [root@linuxprobe ~]# dd if=/dev/zero of=/vo/file bs=100M count=1
    1+0 records in
    1+0 records out
    104857600 bytes (105 MB) copied, 6.69058 s, 15.7 MB/s
    [root@linuxprobe ~]# lvdisplay
    --- Logical volume ---
    LV Path /dev/storage/vo
    LV Name vo
    VG Name storage
    LV UUID MsMB2G-FHiP-Jy61-8pf6-HYKv-pn7A-gg9Jv7
    LV Write Access read/write
    LV Creation host, time linuxprobe.com, 2019-06-17 21:56:38 -0400
    LV snapshot status source of
    SNAP [active]
    LV Status available

    open 1

    LV Size 120.00 MiB
    Current LE 30
    Segments 1
    Allocation inherit
    Read ahead sectors auto

  • currently set to 8192
    Block device 253:0

    --- Logical volume ---
    LV Path /dev/storage/SNAP
    LV Name SNAP
    VG Name storage
    LV UUID ICNPSs-Ey69-H1lf-djyZ-xqhD-J78F-vaqrzq
    LV Write Access read/write
    LV Creation host, time linuxprobe.com, 2019-06-17 22:14:16 -0400
    LV snapshot status active destination for vo
    LV Status available

    open 0

    LV Size 120.00 MiB
    Current LE 30
    COW-table size 120.00 MiB
    COW-table LE 30
    Allocated to snapshot 83.72% #发现存储空间占用量上升了;
    Snapshot chunk size 4.00 KiB
    Segments 1
    Allocation inherit
    Read ahead sectors auto

  • currently set to 8192
    Block device 253:1
    **第 5 步:** 测试 SNAP 快照卷的效果。

    [root@linuxprobe ~]# umount /vo #先卸载逻辑卷设备与目录的挂载。
    [root@linuxprobe ~]# lvconvert --merge /dev/storage/SNAP
    Merging of volume SNAP started.
    vo: Merged: 25.5%
    vo: Merged: 100.0%
    Merge of snapshot into logical volume vo has finished.
    Logical volume "SNAP" successfully removed
    [root@linuxprobe ~]# ls /vo
    lost+found test.txt

    
    ## 删除逻辑卷
    >当生产环境想要重新部署 LVM 或者不再需要使用 LVM 时,则需要执行 LVM 的删除操作。为此,需要提前备份好重要的数据信息,然后依次删除逻辑卷、卷组、物理卷设备

实验:删除逻辑卷
第 1 步: 取消逻辑卷与目录的挂载关联,并删除配置文件/etc/fstab永久生效的参数。

[root@linuxprobe ~]# umount /vo
[root@linuxprobe ~]# vim /etc/fstab 

第 2 步: 删除逻辑卷设备。

[root@linuxprobe ~]# lvremove /dev/storage/vo 
Do you really want to remove active logical volume vo? [y/n]: y
  Logical volume "vo" successfully removed

第 3 步: 删除卷组信息。

[root@linuxprobe ~]# vgremove storage 
  Volume group "storage" successfully removed

第 4 步: 删除物理卷设备。

[root@linuxprobe ~]# pvremove /dev/sdb /dev/sdc
  Labels on physical volume "/dev/sdb" successfully wiped
  Labels on physical volume "/dev/sdc" successfully wiped

iptables 与 firewalld 防火墙

防火墙管理工具

防火墙主要作用是在公网和企业内网之间充当保护屏障,有软硬件之分。但主要功能是依据策略对穿越防火墙自身的流量进行过滤。防火墙策略可以基于流量的源目地址、端口号、协议、应用等信息来定制,然后防火墙使用预先定制的策略规则监控出入的流量,若流量与某一条策略规则相匹配,则执行相应的处理,反之则丢弃。
Linux 就该这么学(RHEL7)

RHEL 7系统中,firewalld 防火墙取代了 RHEL 6 中的 iptables 防火墙,其实 iptables 与 firewalld 都不是真正的防火墙,它们只是用来定义防火墙策略的防火墙管理工具,或者说它们只是一种服务。iptables 服务会把配置好的防火墙策略交由内核层面的 netfilter网络过滤器来处理。而 firewalld 服务则是把配置好的防火墙策略交由内核层面的 netables 包过滤框架来处理。Linux系统存在多个防火墙管理工具,旨在方便运维人员管理 Linux 系统中的防火墙策略,掌握其中一两个即可。

iptables

策略与规则链

防火墙会从上至下的顺序来读取配置的策略规则,在找到匹配项后就立即借宿匹配工作,并去执行匹配项中定义的行为(放行或阻止),如果在读取完所有的策略规则后没有匹配项,就去执行默认的策略。一般防火墙策略规则设置有两种:一种是“通”,即放行,一种是“堵”,即阻止。当防火墙设置的默认规则为拒绝时,就要设置允许规则,否则谁都进不来;如果防火墙设置的默认策略为允许时,就要设置拒绝规则,否则谁都可以进来,防火墙也就失去了防范作用。

iptables 服务把用于处理或过滤流量的策略称之为规则,多条规则可以组成一个规则链,而规则链则依据数据包处理位置的不同进行分类,具体如下:

  • 在进行路由选择前处理数据包(PREROUTING);
  • 处理流入的数据包(INPUT);
  • 处理流出的数据包(OUTPUT);
  • 处理转发的数据包(FORWARD);
  • 在进行路由选择后处理数据包(POSTROUTING);

    iptables 中基本的命令参数

    <center>iptables 常用的参数以及作用</center>

参数 作用
-P 设置默认策略
-F 清空规则链
-L 查看规则链
-A 在规则链的末尾加入新规则
-I num 在规则链的头部加入新规则
-D num 删除某一条规则
-s 匹配来源地址 IP/MASK,加叹号“!”表示除这个 IP 外
-d 匹配目标地址
-i 网卡名称 匹配从这块网卡流入的数据
-o 网卡名称 匹配从这块网卡流出的数据
-p 匹配协议,如 TCP、UDP、ICMP
--dport num 匹配目标端口号
--sport num 匹配来源端口号

查看已有的防火墙规则链。

[root@linuxprobe ~]# iptables -L

清空已有的防火墙规则链。

[root@linuxprobe ~]# iptables -F

把 INPUT 规则链的默认策略设置为拒绝。

[root@linuxprobe ~]# iptables -P INPUT DROP  #把 INPUT 规则链设置为拒绝;
[root@linuxprobe ~]# iptables -L
Chain INPUT (policy DROP)
target     prot opt source               destination        

向 INPUT 规则链中添加允许 ICMP 流量进入策略。

[root@linuxprobe ~]# iptables -I INPUT -p icmp -j ACCEPT 
[root@linuxprobe ~]# iptables -L
Chain INPUT (policy DROP)
target     prot opt source               destination         
ACCEPT     icmp --  anywhere             anywhere   

删除 INPUT 规则链中刚才加入的策略(允许 ICMP 流量),并把默认策略设置为允许。

[root@linuxprobe ~]# iptables -D INPUT 1
[root@linuxprobe ~]# iptables -P INPUT ACCEPT
[root@linuxprobe ~]# iptables -L
Chain INPUT (policy ACCEPT)
target     prot opt source               destination         

将 INPUT 规则链设置为只允许指定网段的主机访问本机的 22 端口,拒绝来自其他所有主机的流量。

[root@linuxprobe ~]# iptables -I INPUT -s 192.168.43.0/24 -p tcp --dport 22 -j ACCEPT 
[root@linuxprobe ~]# iptables -A INPUT -p tcp --dport 22 -j REJECT 
[root@linuxprobe ~]# iptables -L
Chain INPUT (policy ACCEPT)
target     prot opt source               destination         
ACCEPT     tcp  --  192.168.43.0/24      anywhere             tcp dpt:ssh
REJECT     tcp  --  anywhere             anywhere             tcp dpt:ssh reject-with icmp-port-unreachable

向 INPUT 规则链中添加拒绝所有人访问本机的 12345 端口。

[root@linuxprobe ~]# iptables -I INPUT -p tcp --dport 12345 -j REJECT 
[root@linuxprobe ~]# iptables -I INPUT -p udp --dport 12345 -j REJECT 
Chain INPUT (policy ACCEPT)
target     prot opt source               destination         
REJECT     udp  --  anywhere             anywhere             udp dpt:italk reject-with icmp-port-unreachable
REJECT     tcp  --  anywhere             anywhere             tcp dpt:italk reject-with icmp-port-unreachable

向 INPUT 规则链中添加拒绝 192.168.10.5 主机访问本机 80 端口(Web 服务)。

[root@linuxprobe ~]# iptables -I INPUT -s 192.168.10.5 -p tcp --dport 80 -j REJECT 
[root@linuxprobe ~]# iptables -L
Chain INPUT (policy ACCEPT)
target     prot opt source               destination         
REJECT     tcp  --  192.168.10.5         anywhere             tcp dpt:http reject-with icmp-port-unreachable

向 INPUT 规则链中添加拒绝所有主机访问本机 1000~1024 端口。

[root@linuxprobe ~]# iptables -A INPUT -p tcp --dport 1000:1024 -j REJECT 
[root@linuxprobe ~]# iptables -A INPUT -p udp --dport 1000:1024 -j REJECT 
[root@linuxprobe ~]# iptables -L
REJECT     tcp  --  anywhere             anywhere             tcp dpts:cadlock2:1024 reject-with icmp-port-unreachable
REJECT     udp  --  anywhere             anywhere             udp dpts:cadlock2:1024 reject-with icmp-port-unreachable

注意:使用 iptables 配置的防火墙规则默认会在系统下一次重启时失效,如果让配饰的防火墙策略永久生效,还要执行保存命令:

[root@linuxprobe ~]# service iptables save
iptables: Saving firewall rules to /etc/sysconfig/iptables:[  OK  ]

firewalld

firewalld(Dynamic Firewall Manager of Linux systems,Linux 系统的动态防火墙管理器)服务是 RHEL 7 中默认的防火墙配置管理工具,它拥有基于 CLI (命令行界面)和基于 GUI(图型用户界面)两种管理方式。
相较于传统的防火墙管理配置工具,firewalld 支持动态更新技术并加入了区域(zone)的概念。简单来说,区域就是 firewalld 预先准备了几套防火墙策略集合(策略模板),用户可以根据生产场景的不同而选择合适的策略集合,从而实现防火墙策略之间的快速切换。

<center>firewalld 中常用的区域名称及策略规则</center>

区域 默认策略规则
trusted 允许所有的数据包
home 拒绝流入的流量,除非与流出的流量相关;而如果流量与 ssh、mdns、ipp-client、amba-client 与 dhcpv6-client 服务相关,则允许流量
internal 等同于 home 区域
work 拒绝流入的流量,除非与流出的流量数相关;而如果流量与 ssh、ipp-client 与 dhcpv6-client 服务相关,则允许流量
public 拒绝流入的流量,除非与流出的流量相关;而如果流量与 ssh、dpcpv6-client 服务相关,则允许流量
external 拒绝流入的流量,除非与流出的流量相关;而如果流量与 ssh 服务相关,则允许流量
dmz 拒绝流入的流量,除非与流出的流量相关;而如果流量与 ssh 服务相关则允许流量
block 拒绝流入的流量,除非与流出的流量相关
drop 拒绝流入的流浪,除非与流出的流量相关

使用 Apache 服务部署静态网站

第 1 步: 把光盘中的系统镜像挂载到 /media/cdrom 目录中。

[root@linuxprobe ~]# mkdir -p /media/cdrom
[root@linuxprobe ~]# mount /dev/cdrom /media/cdrom/
mount: /dev/sr0 is write-protected, mounting read-only

第 2 步: 使用 vim 创建 Yum 仓库的配置文件。

[root@linuxprobe ~]# vim /etc/yum.repos.d/rhel7.repo
[root@linuxprobe ~]# cat /etc/yum.repos.d/rhel7.repo
[RHEL7]
name=rhel7
baseurl=file:///media/cdrom
enabled=1
gpgcheck=0

第 3 步: 安装 Apache 服务。

[root@linuxprobe ~]# 
[root@linuxprobe ~]# 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.
RHEL7                                                                           | 4.1 kB  00:00:00     
(1/2): RHEL7/group_gz                                                           | 134 kB  00:00:00     
(2/2): RHEL7/primary_db                                                         | 3.4 MB  00:00:00     
Resolving Dependencies
--> Running transaction check
---> Package httpd.x86_64 0:2.4.6-17.el7 will be installed
--> Processing Dependency: httpd-tools = 2.4.6-17.el7 for package: httpd-2.4.6-17.el7.x86_64

第 4 步: 启动 httpd 服务并将其加入开机自启动。

[root@linuxprobe ~]# systemctl start httpd
[root@linuxprobe ~]# systemctl enable httpd
ln -s '/usr/lib/systemd/system/httpd.service' '/etc/systemd/system/multi-user.target.wants/httpd.service'

第 5 步: 测试。
Linux 就该这么学(RHEL7)

配置服务文件参数

<center>Linux 系统中的配置文件</center>

配置文件的名称 存放位置
服务目录 /etc/httpd
主配置文件 /etc/httpd/conf/httpd.conf
网站数据目录 /var/www/html
访问日志 /var/log/httpd/access_log
错误日志 /var/log/httpd/error_log

在 httpd 服务程序的主配置文件中,存在三种类型的信息:注释行信息、全局配置、区域配置。
Linux 就该这么学(RHEL7)

<center>配置 httpd 服务常用参数以及用途</center>

参数 用途
ServerRoot 服务目录
ServerAdmin 管理员邮箱
User 运行服务的用户
Group 运行服务的用户组
ServerName 网站服务器的域名
DocumentRoot 网站数据目录
Directory 网站数据目录的权限
Listen 监听的 IP 地址与端口号
DirectoryIndex 默认的索引页页面
ErrorLog 错误日志文件
CustomLog 访问日志文件
Timeout 网页超时时间,默认为 300 秒

DocumentRoot 参数用于定义网站数据的保存路径,其参数的默认值是把网站数据存放到/var/www/html目录中。

  • /var/www/html写入一个文件,名称为 index.html,刷新并观察网页变化。
    [root@linuxprobe ~]# echo "welcome to jackson.com" >>/var/www/html/index.html

    Linux 就该这么学(RHEL7)
    更改网站数据的保存目录,并创建首页文件
    创建新数据保存目录,并更改配置文件默认的保存数据的目录。

    [root@linuxprobe ~]# mkdir -p /home/wwwroot
    [root@linuxprobe ~]# vim /etc/httpd/conf/httpd.conf
    #
    DocumentRoot "/home/wwwroot"
    #
    # Relax access to content within /var/www.
    #
    <Directory "/home/wwwroot">
    AllowOverride None
    # Allow open access:
    Require all granted
    </Directory>

    创建新的首页文件。

    [root@linuxprobe ~]# echo "welcome to jackson.com" >>/var/www/html/index.html

    重启 httpd 服务。

    [root@linuxprobe ~]# systemctl restart httpd

    重新访问网页 (发现看到的依然是 httpd 服务默认的首页面)
    Linux 就该这么学(RHEL7)
    输入http://127.0.0.1/index.html,显示的是如下页面(SELinux 捣鬼
    Linux 就该这么学(RHEL7)

    SELinux 安全子系统

    SELinux(Security-ENHANCED Linux)是美国国家安全局在 Linux 开源社区的帮助下开发的一个强制访问控制(MAC,Mandatory Access Control)的安全子系统。RHEL 7 系统使用 SELinux 技术的目的是为了让各个服务进程都收到约束,使其仅获取到本应获取的资源。

SELinux 服务有三种配置模式

  • enforcing: 强制启用安全策略模式,将拦截服务的不合法请求。
  • peerissive: 遇到服务越权访问时止发出警告而不强制拦截。
  • disabled: 对于越权的行为不警告也不拦截。

  • SELinux 服务主配置文件
[root@linuxprobe ~]# vim /etc/selinux/config 
[root@linuxprobe ~]# cat /etc/selinux/config

# This file controls the state of SELinux on the system.
# SELINUX= can take one of these three values:
#     enforcing - SELinux security policy is enforced.
#     permissive - SELinux prints warnings instead of enforcing.
#     disabled - No SELinux policy is loaded.
SELINUX=enforcing
# SELINUXTYPE= can take one of these two values:
#     targeted - Targeted processes are protected,
#     minimum - Modification of targeted policy. Only selected processes are protected. 
#     mls - Multi Level Security protection.
SELINUXTYPE=targeted 

使用getenforce命令查看当前 SELinux 服务的运行模式。

[root@linuxprobe ~]# getenforce 
Enforcing

使用setenforce [0|1]命令修改 SELinux 当前运行模式(0 为禁用,1 为启用)。但这种方式只是临时的,在系统重启后就会失效。

[root@linuxprobe ~]# getenforce 
Permissive

再次刷新页面,就会看到正常的页面内容
Linux 就该这么学(RHEL7)

小结: httpd 服务的功能是允许用户访问网站内容,因此 SELinux 肯定会默认放行用户对网站的请求操。但是我们将网站数据的默认保存目录修改为了/home/wwwroot,而/home目录是用来存放普通用户的家目录数据的,而 httpd 提供的网站服务却要获取普通用户家目录中的数据,因而违反了 SELinux 的监管原则。

把 SELinux 服务恢复到强制启用安全策略模式,然后分别查看原始网站数据的保存目录与当前网站数据的保存目录是否拥有不同的 SELinux 安全上下文。

[root@linuxprobe ~]# setenforce 1
[root@linuxprobe ~]# ls -Zd /var/www/html/
drwxr-xr-x. root root system_u:object_r:httpd_sys_content_t:s0 /var/www/html/
[root@linuxprobe ~]# ls -Zd /home/wwwroot/
drwxr-xr-x. root root unconfined_u:object_r:home_root_t:s0 /home/wwwroot/

在文件上设置的 SELinux 安全上下文是由用户段、角色段以及类型段等多个信息项共同组成的。其中,用户段 system_u 代表系统进程的身份,角色段 object_r代表文件目录的角色,类型段 httpd_sys_content_t 代表网站服务的系统文件。由于SELinux 服务比较复杂,目前只需要会使用semanage命令修改上下文跟原始网站目录一致即可。

semanage 命令

semanage 命令用于管理 SELinux 的策略。

格式: “ semanage [选项] [文件]”。

<center>semanage 命令的参数以及功能</center>

参数 功能
-l 用于查询
-a 用于添加
-m 用于修改
-d 用于删除

向网站数据目录中新添加一条 SELinux 安全上下文,让这个目录以及里面的所有文件能够被 httpd 服务程序所访问。

[root@linuxprobe ~]# semanage fcontext -a -t httpd_sys_content_t /home/wwwroot
[root@linuxprobe ~]# semanage fcontext -a -t httpd_sys_content_t /home/wwwroot/*

使用 restorecon 命令将设置好的 SELinux 安全上下文生效。

[root@linuxprobe ~]# restorecon -Rv /home/wwwroot/  #-Rv 参数对指定目录进行递归操作,以及显示 SELinux 安全上下文的修改过程。
restorecon reset /home/wwwroot context unconfined_u:object_r:home_root_t:s0->unconfined_u:object_r:httpd_sys_content_t:s0
restorecon reset /home/wwwroot/index.html context unconfined_u:object_r:home_root_t:s0->unconfined_u:object_r:httpd_sys_content_t:s0

此时 ,将防火墙策略设置为 enforcing 状态,测试网页是否能访问。

[root@linuxprobe ~]# getenforce 
Enforcing

Linux 就该这么学(RHEL7)

个人用户主页功能

若想在系统中为每个用户建立一个独立的网站,通常的方法是居于虚拟网站主机功能来部署多个网站。但对于用户量庞大的情况下,对于管理员来说,工作量巨大,而且用户在自行管理网站也会遇到各种权限限制。而 httpd 服务程序提供的个人用户主页功能可以让系统内所有用户在自己的家目录中管理个人的网站,而且访问起来也很方便。

第 1 步: httpd 服务默认没有开启个人用户主页功能。编辑配置文件,注释第 17 行的 UserDir disabled(表示让 httpd 服务开启个人用户主页功能)。取消第 24 行的 UserDir public_html 的注释(UserDir 参数表示网站数据在用户家目录中的保存目录名称,即 public_html 目录)。

  1 #
  2 # UserDir: The name of the directory that is appended onto a user's home
  3 # directory if a ~user request is received.
  4 #
  5 # The path to the end user account 'public_html' directory must be
  6 # accessible to the webserver userid.  This usually means that ~userid
  7 # must have permissions of 711, ~userid/public_html must have permissions
  8 # of 755, and documents contained therein must be world-readable.
  9 # Otherwise, the client will only receive a "403 Forbidden" message.
 10 #
 11 <IfModule mod_userdir.c>
 12     #
 13     # UserDir is disabled by default since it can confirm the presence
 14     # of a username on the system (depending on home directory
 15     # permissions).
 16     #
 17     #UserDir disabled
 18 
 19     #
 20     # To enable requests to /~user/ to serve the user's public_html
 21     # directory, remove the "UserDir disabled" line above, and uncomment
 22     # the following line instead:
 23     # 
 24     UserDir public_html
 25 </IfModule>
 26 
 27 #
 28 # Control access to UserDir directories.  The following is an example
 29 # for a site where these directories are restricted to read-only.
 30 #
 31 <Directory "/home/*/public_html">
 32     AllowOverride FileInfo AuthConfig Limit Indexes
 33     Options MultiViews Indexes SymLinksIfOwnerMatch IncludesNoExec
 34     Require method GET POST OPTIONS
 35 </Directory>

第 2 步: 在用户家目录中建立用于保存网站数据的目录及首页面文件。还需将家目录的权限修改为 755,保证其他人也有权限访问里面的内容。

[root@linuxprobe ~]# su - jackson
[jackson@linuxprobe ~]$ mkdir public_html
[jackson@linuxprobe ~]$ echo "this is jackson's website" > public_html/index.html
[jackson@linuxprobe ~]$ chmod -Rf 755 /home/jackson/

第 3 步: 重新启动 httpd 服务,浏览器输入网址测试,格式:“网址/~用户名”,此时并么有看到用户的个人网站,而是一个报错的页面(SELinux惹的祸)。

[jackson@linuxprobe ~]$ su -
Password: 
Last login: Fri Jun 21 11:48:16 EDT 2019 on :0
Last failed login: Fri Jun 21 11:48:51 EDT 2019 on pts/1
There was 1 failed login attempt since the last successful login.
[root@linuxprobe ~]# systemctl restart httpd

Linux 就该这么学(RHEL7)
第 4 步: 思考。httpd 服务在提供个人用户主页功能时,该用户的网站数据目录本身就应该是存放到与这位用户对应的家目录中,所以应该不需要修改家目录的 SELinux 安全上下文。Linux 域概念(Linux 域确保服务程序不能执行违规的操作,只能本分地为用户提供服务。httpd 服务中突然开启的这项个人用户主页功能到底有没有被 SELinux 域默认允许呢?)

  • 使用getsebool命令查询并过滤出所有与 HTTP 协议相关的安全策略。其中,off 为禁止状态,on 为允许状态
    [root@linuxprobe ~]# getsebool -a |grep http
    httpd_anon_write --> off
    httpd_builtin_scripting --> on
    httpd_can_check_spam --> off
    httpd_can_connect_ftp --> off
    httpd_can_connect_ldap --> off
    httpd_can_connect_mythtv --> off
    httpd_can_connect_zabbix --> off
    httpd_can_network_connect --> off
    httpd_can_network_connect_cobbler --> off
    httpd_can_network_connect_db --> off
    httpd_can_network_memcache --> off
    httpd_can_network_relay --> off
    httpd_can_sendmail --> off
    httpd_dbus_avahi --> off
    httpd_dbus_sssd --> off
    httpd_dontaudit_search_dirs --> off
    httpd_enable_cgi --> on
    httpd_enable_ftp_server --> off
    httpd_enable_homedirs --> off
    httpd_execmem --> off
    httpd_graceful_shutdown --> on
    httpd_manage_ipa --> off
    httpd_mod_auth_ntlm_winbind --> off
    httpd_mod_auth_pam --> off
    httpd_read_user_content --> off
    httpd_run_stickshift --> off
    httpd_serve_cobbler_files --> off
    httpd_setrlimit --> off
    httpd_ssi_exec --> off
    httpd_sys_script_anon_write --> off
    httpd_tmp_exec --> off
    httpd_tty_comm --> off
    httpd_unified --> off
    httpd_use_cifs --> off
    httpd_use_fusefs --> off
    httpd_use_gpg --> off
    httpd_use_nfs --> off
    httpd_use_openstack --> off
    httpd_use_sasl --> off
    httpd_verify_dns --> off
    named_tcp_bind_http_port --> off
    prosody_bind_http_port --> off

    通过以上 SELinux 域安全策略规则可以发现 httpd 服务的个人用户主页功能时关闭状态 httpd_enable_homedirs --&gt; off,通过setsebool命令来修改 SELinux 策略,记得要加上-P参数让修改后的 SELinux 策略规则永久生效且立即生效。随后刷新网站,观察效果。

    [root@linuxprobe ~]# setsebool -P httpd_enable_homedirs=on

    Linux 就该这么学(RHEL7)
    有时网站并不希望直接将网页内容显示出来,只想让通过身份验证的用户访客看到里面的内容,这时可以在网站中添加口令功能。

第 1 步: 先使用htpasswd命令生成密码数据库。-c参数表示第一次生成;然后再分别添加密码数据库存放文件,以及验证要用到的用户名称(该用户不必是系统中已有的本地账户)。

[root@linuxprobe ~]# htpasswd -c /etc/httpd/passwd jackson
New password: #此处输入用于网页验证的密码;
Re-type new password:  #确认密码;
Adding password for user jackson

第 2 步: 编辑个人用户主页功能的配置文件。把 31 ~ 35 行的参数信息修改成以下内容。

 31 <Directory "/home/*/public_html">
 32     AllowOverride all
 33     authuserfile "/etc/httpd/passwd"  #生成用于密码验证的文件保存路径;
 34     authname "My Privately Website"  #当用户尝试访问个人个人用户网站时的提示信息;
 35     authtype basic
 36     require user jackson  #用户进行账户密码登录时需要验证的用户名称;
 37 </Directory>

第 3 步: 重启 httpd 服务,让配置生效。

[root@linuxprobe ~]# systemctl restart httpd

第 4 步: 测试。当用户再想访问某个用户的个人网站时,就必须输入账户和密码才能正常访问(注意:输入的密码是 htpasswd 命令生成的专门用于网站登录的口令密码)。

Linux 就该这么学(RHEL7)
Linux 就该这么学(RHEL7)

虚拟主机功能

Apache 的虚拟主机功能是服务器基于用户请求的不同 IP 地址、主机域名或端口号,实现提供多个网站同时为外部提供访问服务的技术。

基于 IP 地址

如果一台服务器有多个 IP 地址,而且每个 IP 地址与服务器上部署的每个网站一一对应,这样当用户请求访问不同的 IP 地址时,会访问到不同网站的页面资源。

第 1 步: 使用nmtui命令配置网络参数。
Linux 就该这么学(RHEL7)
第 2 步: 重启网络让配置生效,并测试网络连通性。

[root@linuxprobe ~]# systemctl restart network
[root@linuxprobe ~]# ping 192.168.10.10
PING 192.168.10.10 (192.168.10.10) 56(84) bytes of data.
64 bytes from 192.168.10.10: icmp_seq=1 ttl=64 time=0.049 ms
^C
--- 192.168.10.10 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.049/0.049/0.049/0.000 ms
[root@linuxprobe ~]# ping 192.168.10.20
PING 192.168.10.20 (192.168.10.20) 56(84) bytes of data.
64 bytes from 192.168.10.20: icmp_seq=1 ttl=64 time=0.049 ms
^C
--- 192.168.10.20 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.049/0.049/0.049/0.000 ms
[root@linuxprobe ~]# ping 192.168.10.30
PING 192.168.10.30 (192.168.10.30) 56(84) bytes of data.
64 bytes from 192.168.10.30: icmp_seq=1 ttl=64 time=0.040 ms
^C
--- 192.168.10.30 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.040/0.040/0.040/0.000 ms

第 3 步: 分别在/home/wwwroot中创建用于保存不同网站数据的 3 个目录,并向其中写入网站的首页文件。

[root@linuxprobe ~]# mkdir -p /home/wwwroot/10
[root@linuxprobe ~]# mkdir -p /home/wwwroot/20
[root@linuxprobe ~]# mkdir -p /home/wwwroot/30
[root@linuxprobe ~]# echo "ip 192.168.10.10" >/home/wwwroot/10/index.html
[root@linuxprobe ~]# echo "ip 192.168.10.20" >/home/wwwroot/20/index.html
[root@linuxprobe ~]# echo "ip 192.168.10.30" >/home/wwwroot/30/index.html

第 4 步: 创建挂载点兵挂载光盘。

[root@linuxprobe ~]# vim /etc/yum.repos.d/RHEL7.repo
    [RHEL7]
    name=rhel7
    baseurl=file:///media/cdrom
    enabled=1
    gpgcheck=0
[root@linuxprobe ~]# mkdir -p /media/cdrom
[root@linuxprobe ~]# echo "/dev/cdrom /media/cdrom iso9660 defaults 0 0" >>/etc/fstab 
[root@linuxprobe ~]# mount -a
mount: /dev/sr0 is write-protected, mounting read-only

第 5 步: 安装 httpd 服务。

[root@linuxprobe ~]# yum install httpd -y

第 6 步: 在 httpd 服务的配置文件中,100 多行位置,分别追加写入三个基于 IP 地址的虚拟主机网站参数,。

122 #
123 <VirtualHost 192.168.10.20>
124 DocumentRoot /home/wwwroot/20
125 ServerName bbs.jackson.com
126 <Directory /home/wwwroot/20 >
127 AllowOverride None
128 Require all granted
129 </Directory>
130 </VirtualHost>
131 #
132 <VirtualHost 192.168.10.30>
133 DocumentRoot /home/wwwroot/30
134 ServerName tech.jackson.com
135 <Directory /home/wwwroot/30 >
136 AllowOverride None
137 Require all granted
138 </Directory>
139 </VirtualHost>

第 7 步: 重启服务。

[root@linuxprobe ~]# systemctl restart httpd

第 8 步: 此时访问网页发现还是默认页面。还需要修改 SELinux 安全上下文。

[root@linuxprobe ~]# semanage fcontext -a -t httpd_sys_content_t /home/wwwroot
[root@linuxprobe ~]# ls -Zd /home/wwwroot/
drwxr-xr-x. root root unconfined_u:object_r:home_root_t:s0 /home/wwwroot/
[root@linuxprobe ~]# semanage fcontext -a -t httpd_sys_content_t /home/wwwroot/10
[root@linuxprobe ~]# semanage fcontext -a -t httpd_sys_content_t /home/wwwroot/10/*
[root@linuxprobe ~]# semanage fcontext -a -t httpd_sys_content_t /home/wwwroot/20
[root@linuxprobe ~]# semanage fcontext -a -t httpd_sys_content_t /home/wwwroot/20/*
[root@linuxprobe ~]# semanage fcontext -a -t httpd_sys_content_t /home/wwwroot/30
[root@linuxprobe ~]# semanage fcontext -a -t httpd_sys_content_t /home/wwwroot/30/*
[root@linuxprobe ~]# restorecon -Rv /home/wwwroot/
restorecon reset /home/wwwroot context unconfined_u:object_r:home_root_t:s0->unconfined_u:object_r:httpd_sys_content_t:s0
restorecon reset /home/wwwroot/10 context unconfined_u:object_r:home_root_t:s0->unconfined_u:object_r:httpd_sys_content_t:s0
restorecon reset /home/wwwroot/10/index.html context unconfined_u:object_r:home_root_t:s0->unconfined_u:object_r:httpd_sys_content_t:s0
restorecon reset /home/wwwroot/20 context unconfined_u:object_r:home_root_t:s0->unconfined_u:object_r:httpd_sys_content_t:s0
restorecon reset /home/wwwroot/20/index.html context unconfined_u:object_r:home_root_t:s0->unconfined_u:object_r:httpd_sys_content_t:s0
restorecon reset /home/wwwroot/30 context unconfined_u:object_r:home_root_t:s0->unconfined_u:object_r:httpd_sys_content_t:s0
restorecon reset /home/wwwroot/30/index.html context unconfined_u:object_r:home_root_t:s0->unconfined_u:object_r:httpd_sys_content_t:s0
[root@linuxprobe ~]# ls -Zd /home/wwwroot/
drwxr-xr-x. root root unconfined_u:object_r:httpd_sys_content_t:s0 /home/wwwroot/
[root@linuxprobe ~]# ls -Zd /home/wwwroot/*
drwxr-xr-x. root root unconfined_u:object_r:httpd_sys_content_t:s0 /home/wwwroot/10
drwxr-xr-x. root root unconfined_u:object_r:httpd_sys_content_t:s0 /home/wwwroot/20
drwxr-xr-x. root root unconfined_u:object_r:httpd_sys_content_t:s0 /home/wwwroot/30

第 9 步: 重新刷新网页。
Linux 就该这么学(RHEL7)
Linux 就该这么学(RHEL7)
Linux 就该这么学(RHEL7)

基于主机域名

当服务器无法为每个网站都分配一个独立 IP 地址的时候,可以尝试让 Apache 自动识别用户请求的域名,从而根据不同的域名请求来传输不同的内容。

第 1 步: 定义 IP 与 域名的映射关系。

127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
192.168.10.10 www.jackson.com bbs.jackson.com tech.jackson.com

第 2 步: 使用ping命令验证域名是否成功解析为 IP 地址。

[root@linuxprobe ~]# ping -c 2 www.jackson.com
PING www.jackson.com (192.168.10.10) 56(84) bytes of data.
64 bytes from www.jackson.com (192.168.10.10): icmp_seq=1 ttl=64 time=0.045 ms
64 bytes from www.jackson.com (192.168.10.10): icmp_seq=2 ttl=64 time=0.061 ms

--- www.jackson.com ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 999ms
rtt min/avg/max/mdev = 0.045/0.053/0.061/0.008 ms
[root@linuxprobe ~]# ping -c 2 bbs.jackson.com
PING www.jackson.com (192.168.10.10) 56(84) bytes of data.
64 bytes from www.jackson.com (192.168.10.10): icmp_seq=1 ttl=64 time=0.037 ms
64 bytes from www.jackson.com (192.168.10.10): icmp_seq=2 ttl=64 time=0.143 ms

--- www.jackson.com ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 999ms
rtt min/avg/max/mdev = 0.037/0.090/0.143/0.053 ms
[root@linuxprobe ~]# ping -c 2 tech.jackson.com
PING www.jackson.com (192.168.10.10) 56(84) bytes of data.
64 bytes from www.jackson.com (192.168.10.10): icmp_seq=1 ttl=64 time=0.036 ms
64 bytes from www.jackson.com (192.168.10.10): icmp_seq=2 ttl=64 time=0.045 ms

--- www.jackson.com ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 999ms
rtt min/avg/max/mdev = 0.036/0.040/0.045/0.007 ms

第 3 步: 分别在 /home/wwwroot 目录中创建用于保存不同网站数据 的三个目录,并写入网站首页文件。

[root@linuxprobe ~]# mkdir -p /home/wwwroot/www
[root@linuxprobe ~]# mkdir -p /home/wwwroot/bbs
[root@linuxprobe ~]# mkdir -p /home/wwwroot/tech
[root@linuxprobe ~]# echo "www.jackson.com" > /home/wwwroot/www/index.html
[root@linuxprobe ~]# echo "bbs.jackson.com" > /home/wwwroot/bbs/index.html
[root@linuxprobe ~]# echo "tech.jackson.com" > /home/wwwroot/tech/index.html

第 4 步: 分别写入三个基于主机名的虚拟主机网站参数。

113 #
114 <VirtualHost 192.168.10.10>
115 DocumentRoot "/home/wwwroot/www"
116 ServerName "www.jackson.com"
117 <Directory "/home/wwwroot/www">
118 AllowOverride None
119 Require all granted
120 </Directory>
121 </VirtualHost>
122 #
123 <VirtualHost 192.168.10.10>
124 DocumentRoot "/home/wwwroot/bbs"
125 ServerName "bbs.jackson.com"
126 <Directory "/home/wwwroot/bbs">
127 AllowOverride None
128 Require all granted
129 </Directory>
130 </VirtualHost>
131 #
132 <VirtualHost 192.168.10.10>
133 DocumentRoot "/home/wwwroot/tech"
134 ServerName "tech.jackson.com"
135 <Directory "/home/wwwroot/tech">
136 AllowOverride None
137 Require all granted
138 </Directory>
139 </VirtualHost>
140 #

第 5 步: 重启 httpd 服务。

[root@linuxprobe ~]# systemctl restart httpd

第 6 步: 修改 SELinux 安全上下文。

[root@linuxprobe ~]# semanage fcontext -a -t httpd_sys_content_t /home/wwwroot
[root@linuxprobe ~]# semanage fcontext -a -t httpd_sys_content_t /home/wwwroot/www
[root@linuxprobe ~]# semanage fcontext -a -t httpd_sys_content_t /home/wwwroot/www/*
[root@linuxprobe ~]# semanage fcontext -a -t httpd_sys_content_t /home/wwwroot/bbs
[root@linuxprobe ~]# semanage fcontext -a -t httpd_sys_content_t /home/wwwroot/bbs/*
[root@linuxprobe ~]# semanage fcontext -a -t httpd_sys_content_t /home/wwwroot/tech
[root@linuxprobe ~]# semanage fcontext -a -t httpd_sys_content_t /home/wwwroot/tech/*

第 7 步: 使用restorecon命令让新配置的 SELinux 安全上下文生效。

[root@linuxprobe ~]# restorecon -Rv /home/wwwroot/
restorecon reset /home/wwwroot context unconfined_u:object_r:home_root_t:s0->unconfined_u:object_r:httpd_sys_content_t:s0
restorecon reset /home/wwwroot/www context unconfined_u:object_r:home_root_t:s0->unconfined_u:object_r:httpd_sys_content_t:s0
restorecon reset /home/wwwroot/www/index.html context unconfined_u:object_r:home_root_t:s0->unconfined_u:object_r:httpd_sys_content_t:s0
restorecon reset /home/wwwroot/bbs context unconfined_u:object_r:home_root_t:s0->unconfined_u:object_r:httpd_sys_content_t:s0
restorecon reset /home/wwwroot/bbs/index.html context unconfined_u:object_r:home_root_t:s0->unconfined_u:object_r:httpd_sys_content_t:s0
restorecon reset /home/wwwroot/tech context unconfined_u:object_r:home_root_t:s0->unconfined_u:object_r:httpd_sys_content_t:s0
restorecon reset /home/wwwroot/tech/index.html context unconfined_u:object_r:home_root_t:s0->unconfined_u:object_r:httpd_sys_content_t:s0

第 8 步: 测试。
Linux 就该这么学(RHEL7)
Linux 就该这么学(RHEL7)
Linux 就该这么学(RHEL7)

基于端口号

基于端口号的虚拟主机功能可以让用户通过制指定的端口号来访问服务器上的网站资源。基于端口号的配置放是也是较为复杂的,不仅要考虑 httpd 服务程序的配置因素,还需要考虑到 SELinux 服务对新开设端口的监控。一般,使用 80、443、8080 等端口来提供网站访问服务是比较合理的,但是使用其他端口会受到 SELinux 服务的限制。

猜你喜欢

转载自blog.51cto.com/10761368/2412367
今日推荐