## 简介
本人之前用的是debian系列的Linux，从2017.06开始使用centos发行版的Linux，所以之后会添加一些关于centos的知识点。

## 基本知识
### linux 常用的命令
简单的就不解释了
```sh
cd、ls、mkdir、tar、rmdir、rm、mv、cp、cat
```
1. `ipcs` 用于显示进程间的通信设备，比如共享内存、信号量。

#### 管道命令
前一个命令的结果作为后一个命令的输入到第二个命令<br>
<span style="color:red;">注意</span><br>
1. 管道命令只处理前一个命令正确输出，不处理错误输出
2. 管道命令右边命令，必须能够接收标准输入流命令才行。

#### 输出重定向
1. `command > file` 将输出重定向到file
2. `command >> file` 讲输出以追加的方式重定向到file
3. `2 > file ,2 >> file` 将stderr重定向到file中
4. `1 > file 1 >> file` 将stdout重定向到file中
5. `command > file 2>&1,command >> file 2>&1` 将 stdout 和 stderr 合并后重定向到 file

#### 输入重定向
与输出重定向相似

#### /dev/null 文件
```sh
command > /dev/null
```
`/dev/null` 是一个特殊的文件，写入到它的内容都会被丢弃；如果尝试从该文件读取内容，那么什么也读不到。
但是 `/dev/null` 文件非常有用，将命令的输出重定向到它，会起到"禁止输出"的效果。

<br><span style="color:red;">注意</span><br>
0 是标准输入（STDIN），1 是标准输出（STDOUT），2 是标准错误输出（STDERR）。

#### 文件时间
##### mtime 修改时间
当该文件的“内容数据”更改时，就会更新这个时间。内容数据指的是文件的内容，而不是文件的属性。

##### ctime 状态时间
当该文件的”状态（status）”改变时，就会更新这个时间，举例来说，更改了权限与属性，就会更新这个时间。

#### atime 存取时间
当“取用文件内容”时，就会更新这个读取时间。举例来说，使用cat去读取 `~/.bashrc`，就会更新atime了。
![看不见](http://www.zeekling.cn/gogs/zeek/study/raw/master/linux/pics/view.jpeg)
![看不见](http://www.zeekling.cn/gogs/zeek/study/raw/master/linux/pics/view2.jpeg)

## vim 用法
 [配置方法及其详细用法](http://www.zeekling.cn/gogs/zeek/vim_config)

## 目录结构
```sh
/bin:常用命令
/boot:启动程序
/dev:设备文件
/etc:启动,关闭,配置程序与文件
/home:用户工作根目录
/lib:共享连接库
/root:超级用户的工作目录
/sbin:系统管理员常用管理程序
/tmp:临时文件
/lost+found:系统出现异常时,用于保存部分资料
/mnt:光驱,硬盘等的挂载点
/media:光驱的自动挂载点
/proc:操作系统的实时信息
/sys:系统中的硬件设备信息
/srv:服务器启动后需要的提取的信息
/var:某些大文件的溢出区，比方说各种服务的日志文件
/usr/bin:众多的应用程序
/usr/sbin:超级用户的一些管理程序
/opt:第三方软件
```

## 权限管理
```sh
➜  ~ ll
total 56K
drwxr-xr-x  2 lzh lzh 4.0K Oct 27 22:37 Desktop
drwxr-xr-x 10 lzh lzh 4.0K Jan  6 21:10 Documents
drwxr-xr-x  9 lzh lzh 4.0K Jan  8 01:30 Downloads

文件权限 - 连接数 - 文件所有者 - 文件所属用户组 - 文件大小 - 文件最后时间 - 文件名字
文件类型1 - 用户权限3 - 用户组权限3 - 其他用户权限3
```

### 权限
* ACL权限
  * 用户
  * 用户组
  * 默认属性
* 特殊权限
  * SUID权限(对单个用户有效)4： 作用于可执行文件，执行者将均有改程序所有者的权限，本权限只在执行过程中有效
  * SGID权限(对用户组有效)2：可作用于可执行文件和目录
    * 对于文件夹：
      1. 使用者若对于此目录具有 r 与 x 的权限时，该使用者能够进入此目录；
      2. 使用者在此目录下的群组将会变成该目录的群组；
      3. 若使用者在此目录下具有 w 的权限(可以新建文件)，则使用者所创建的新文件，该新文件的群组与此目录的群组相同。
    * 对于文件：
      1. SGID 对二进制可执行文件有效；
      2. 程式执行者对于该文件来说，需具备 x 的权限；
      3. 执行者在执行的过程中将会获得该文件群组的支援。
  * SBIT权限(只针对目录有效)1：
      1. 只针对目录有效;
      2. 设置了sbit的文件夹下，用户自己新建的文件只有root和自己能对文件进行操作。

## 文件系统
* ext2,ext3.ext4
* inode

![inode节点示意图](http://www.zeekling.cn/gogs/zeek/study/raw/master/pics/inode1.gif)

1.  软连接
2.  硬链接

## linux 启动过程
###  一般操作系统的启动流程
***通电***-->***BIOS***-->***主引导记录***-->***操作系统***

### 加载内核
操作系统接管硬件以后，首先读入/boot目录下的内核文件。
***操作系统***-->***/boot***-->
如/boot文件夹下面：
```sh
➜  /boot ls
config-4.3.0-kali1-amd64                grub
initrd.img-4.6.0-kali1-amd64    System.map-4.6.0-kali1-amd64
vmlinuz-4.6.0-kali1-amd64               config-4.6.0-kali1-amd64
initrd.img-4.3.0-kali1-amd64    System.map-4.3.0-kali1-amd64
vmlinuz-4.3.0-kali1-amd64
```
### 启动初始化进程
内核文件加载以后，就开始运行第一个程序`/sbin/init`，他的作用是初始化系统环境。
***操作系统***-->***/boot***-->***init进程***-->　
由于init是第一个运行的程序，他的进程编号(pid)就是１。其他所有进程都从它衍生，都是他的子进程。

### 确认运行等级
许多程序需要开机启动。他们在Windows叫做服务，在Linux叫做守护进程。
init进程的一大任务就是去运行这些开机启动的程序。但是，不同的场合需要启动不同的程序，比如：作为服务器需要启动
Apache，其桌面就不需要。linux允许为不同的场合，分配不同的开机启动程序，这就叫做运行级别。也就是说启动的时候根
据运行级别，确认运行那些程序。
***操作系统***-->***/boot***-->***init进程***-->***运行级别***-->
Linux预置七种运行级别(0-6)。一般来说，0是关机，1是单一用户模式(也就是维护模式)，6是重启。运行级别2-5，各个发行
版不太一样。init进程首先读取文件/etc/inittab,他是运行级别的设置文件。但是我在我的kali linux 上面就没有看到这个
文件不知道他去哪儿了，书上全都是骗人的。
<p>运行级别</p>
1. init 0 关机
2. init 1 单用户模式纯命令行界面
3. init 2 不完全多用户模式，不含NFS模式，纯命令行
4. init 3 完全多用户模式，服务正常开启，使我们服务器的默认运行模式
5. init 4 未分配
6. init 5 图形界面
7. init 6 重启

### 加载开机启动程序
***操作系统***-->***/boot***-->***init进程***-->***运行级别***-->***/etc/init.d***-->
```sh
 ➜  ~ ll /etc/rc2.d
 总用量 4.0K
 lrwxrwxrwx 1 root root  17 8月  13 00:09 K01apache2 -> ../init.d/apache2
 lrwxrwxrwx 1 root root  29 8月  15 01:51 K01apache-htcacheclean -> ../init.d/apache-htcacheclean
 lrwxrwxrwx 1 root root  16 8月  13 00:09 K01atftpd -> ../init.d/atftpd
 lrwxrwxrwx 1 root root  18 8月  13 00:09 K01beef-xss -> ../init.d/beef-xss
 lrwxrwxrwx 1 root root  19 8月  13 00:09 K01bluetooth -> ../init.d/bluetooth
 lrwxrwxrwx 1 root root  17 8月  13 00:09 K01couchdb -> ../init.d/couchdb
```
这样做的好处就是如果你要手动关闭或者重启某个进程，直接到目录/etc/init.d中寻找启动脚本即可，比如，重启
Apache服务器，就运行下面命令：

```sh
sudo /etc/init.d/apache2 restart
```

### 用户登陆
开机启动程序加载完毕以后，就要让用户登陆了。
***操作系统***-->***/boot***-->***init进程***-->***运行级别***-->***/etc/init.d***-->***用户登录***-->
一般来说用户登陆方式有三种：
1. 命令行登陆
2. ssh登陆
3. 图形界面登陆

### 进入login shell
所谓的shell，简单说就是命令行界面，让用户直接和操作系统对话。用户登陆时打开shell，就叫做login shell 。
***操作系统***-->***/boot***-->***init进程***-->***运行级别***-->***/etc/init.d***-->***用户登录***-->
***Login shell***-->
1. 命令行模式登陆：首先读入/etc/profile，这是对所有用户都有效的配置；然后依次寻找下面三个文件，这是针对当前用
户的配置(我用的是zsh，所以，这些文件前两个对我没有作用)
```
~/.bash_profile
~/.bash_login
~/.profile
```
2. ssh登陆：与第一种情况完全相同。
3. 图形界面登陆：只加载/etc/profile和~/.profile。也就是说，~/.bash_profile不管有没有，都不会运行。

### 打开non-login shell
上一步完成以后，Linux的启动过程就算结束了，用户已经命令行提示符或者图形界面了
用户进入操作系统后常常会在打开开启一个shell。这个shell 就叫做non-login shell ，意思就是他不同于登陆时出现的那
个shell不读取/etc/profile和.profile等配置文件。
***操作系统***-->***/boot***-->***init进程***-->***运行级别***-->***/etc/init.d***-->***用户登录***-->
***Login shell***-->***Non-login shell***
### 注意
#### login shell 和no-login shell
login shell 每次打开是都要进行登录，no-login shell不用每次都登陆。


### kali linux 源
```sh
deb http://ftp.cn.debian.org/debian jessie main non-free
deb http://http.kali.org/kali kali-rolling main non-free contrib
deb http://mirrors.ustc.edu.cn/kali kali-rolling main non-free contrib
deb http://mirrors.aliyun.com/kali kali-rolling main non-free contrib
deb-src http://mirrors.aliyun.com/kali kali-rolling main non-free contrib
deb http://mirrors.aliyun.com/kali-security kali-rolling/updates main contrib non-free
deb-src http://mirrors.aliyun.com/kali-security kali-rolling/updates main contrib non-free
deb http://mirrors.ustc.edu.cn/kali kali-rolling main non-free contrib
deb-src http://mirrors.ustc.edu.cn/kali kali-rolling main non-free contrib
deb http://mirrors.ustc.edu.cn/kali-security kali-current/updates main contrib non-free
deb-src http://mirrors.ustc.edu.cn/kali-security kali-current/updates main contrib non-free
```

## linux 内存管理
### Linux内存地址空间
#### 内存地址——用户态&内核态
* 用户态：Ring3 运行于用户态的代码则要受到处理器的诸多
* 内核态：Ring0 在处理器的存储保护中，核心态
* 用户态切换到内核态的 3 种方式：系统调用、异常、外设中断
* 区别：每个进程都有完全属于自己的，独立的，不被干扰的内存空间；用户态的程序就不能随意操作内核地址空间，具
  有一定的安全保护作用；内核态线程共享内核地址空间；
![linux](http://www.zeekling.cn/gogs/zeek/study/raw/master/pics/linux2.png)

#### 内存地址——MMU 地址转换
* MMU 是一种硬件电路，它包含两个部件，一个是分段部件，一个是分页部件
* 分段机制把一个逻辑地址转换为线性地址
* 分页机制把一个线性地址转换为物理地址
![分页](http://www.zeekling.cn/gogs/zeek/study/raw/master/pics/linux_page.png)

#### 内存地址——分段机制
* 段选择符
  * 为了方便快速检索段选择符，处理器提供了 6 个分段寄存器来缓存段选择符，它们是： cs,ss,ds,es,fs 和 gs
  * 段的基地址(Base Address)：在线性地址空间中段的起始地址
  * 段的界限(Limit)：在虚拟地址空间中，段内可以使用的最大偏移量
* 分段实现
  * 逻辑地址的段寄存器中的值提供段描述符，然后从段描述符中得到段基址和段界限，然后加上逻辑地址的偏移量，就得到了线性地址

![段](http://www.zeekling.cn/gogs/zeek/study/raw/master/pics/linux_duan.png)

#### 内存地址——分页机制（32 位）
* 分页机制是在分段机制之后进行的，它进一步将线性地址转换为物理地址
* 10 位页目录，10 位页表项， 12 位页偏移地址
* 单页的大小为 4KB
![分页机制](http://www.zeekling.cn/gogs/zeek/study/raw/master/pics/linux_page32.png)

#### 用户态地址空间
![用户态地址空间](http://www.zeekling.cn/gogs/zeek/study/raw/master/pics/user_space.jpg)
* TEXT：代码段可执行代码、字符串字面值、只读变量
* DATA：数据段，映射程序中已经初始化的全局变量
* BSS 段：存放程序中未初始化的全局变量
* HEAP：运行时的堆，在程序运行中使用 malloc 申请的内存区域
* MMAP：共享库及匿名文件的映射区域
* STACK：用户进程栈

#### 内核态地址空间
![内核态地址空间](http://www.zeekling.cn/gogs/zeek/study/raw/master/pics/kernel_space.jpg)
* 直接映射区：线性空间中从 3G 开始最大 896M 的区间，为直接内存映射区
* 动态内存映射区：该区域由内核函数 vmalloc 来分配
* 永久内存映射区：该区域可访问高端内存
* 固定映射区：该区域和 4G 的顶端只有 4k 的隔离带，其每个地址项都服务于特定的用途，如： ACPI_BASE 等

#### 进程内存空间
* 用户进程通常情况只能访问用户空间的虚拟地址，不能访问内核空间虚拟地址
* 内核空间是由内核负责映射，不会跟着进程变化；内核空间地址有自己对应的页表，用户进程各自有不同额页表
![进程内存空间](http://www.zeekling.cn/gogs/zeek/study/raw/master/pics/jingcheng.jpg)

