资讯专栏INFORMATION COLUMN

读书笔记-linux私房菜

robin / 3784人阅读

摘要:私房菜阅读笔记整理计算机的五大单元输入输出内部的控制单元和算数逻辑单元内存主要作用,管理和运算算数逻辑单元,控制单元前者负责程序运算和逻辑判断后者负责协调各个组件与各个单元之间的工作的重点在与运算和判断,这些数据来自于内存内存则从输

《Linux私房菜》阅读笔记整理
chapter 0

计算机的五大单元 - 输入 输出 CPU内部的控制单元和算数逻辑单元 内存

CPU

central processing unit

主要作用,管理和运算 (算数逻辑单元,控制单元) - 前者负责程序运算和逻辑判断 后者负责协调各个组件与各个单元之间的工作

CPU的重点在与 运算和判断,这些数据来自于内存. 内存则从输入单元传输进来,CPU处理完毕之后先传递给内存,再从内存传输到输出单元

目前主流的CPU是双核以上,原本的单核是指仅有一个运算单元,多核是指在一个CPU壳子里装了多个运算内核

CPU 的性能对比

1 内部的微指令集

2 CPU的频率 -- 每秒CPU的工作次数 这个数值越高 代表单位时间内可以做更多的事情

比如某款CPU频率 3GHZ 则其每秒可进行 3 x 10的9次方 工作

外频 倍频

为了加速计算速度,CPU开发商就在CPU内部加上一个加速功能

外频 : CPU与外部组件进行数据传输,运算的频率

倍频: CPU内部用来加速性能的一个倍数

两者相乘才是CPU的频率

超频 -- 有人喜欢将CPU的倍频或者外频通过主板的设定更改为较高频率,但因为CPU的倍频一般在出厂的时候会被确定无法更改,所以一般修改的是外频

比如 3GHZ的CPU设置为超频 可以将外频 333HZ 调整到 400 MHZ 这样主板各个组件运行频率增高 CPU可以到达 3.6GHZ 但是可能造成死机

软件程序运行

设计出一种人类能看懂的语言,然后创造一种“编译器”来将人类写的程序语言转换为机器语言,常见的编译器语言,c c++

操作系统

一组程序,用来管理计算机所有活动以及驱动系统中所有硬件

让CPU开始判断逻辑与运算数值,让内存开始加载数据

以上就是操作系统的内核

硬件由内核管理,那想要去开发软件,就需要去参考这个内核的先关功能,因此操作系统提供了一组开发接口出来

1 操作系统的内核是参考硬件规格写的,所以同一个操作系统不能在不同的硬件架构下运行

2 应用程序的开发是参考操作系统提供的开发接口,所以该应用程序只能在该操作系统中运行

// 直接操作一个硬件设施
音箱 -- 请播放音乐 “黑白格”

// 使用内核
function play (music) {
  const target = "音箱"
  target.播放音乐(music)
}

比如,window的软件不能再Linux中运行

内核

内核主要在于管理硬件,提供合理的资源分配,比如CPU资源 内存使用资源等

程序管理

多任务环境 --- 一部计算机可能同时有很多工作在等待CPU运算处理,内核需要控制这些工作,让CPU做有效分配

良好的CPU调度机制(CPU先让那个工作开始运行),可以加快整体系统性能

内存管理

控制系统的内存

系统所有的程序代码和数据都必须要先放在内存里

文件系统管理

比如数据输入输出 I/O

如果内核不认识某个文件系统,则无法使用此格式的文件

设备驱动

内存

CPU读取的数据都来自与内存,不管是软件程序还是数据,都要先读入内存才可以被使用

个人计算机的内存为

内存容量也很重要,因为数据要先存入内存中

一般内存越大 系统越快,因为不用释放内存内部数据

硬盘

存储数据,实际的数据是写在具有磁性物质的盘片上

linux vs unix chapter 1

什么是Linux

linux 就是一套操作系统

计算机由一堆硬件设备组成,操作系统用户管理控制这些硬件资源(内核)

不止如此,为了程序员可以更好的开发软件,操作系统还提供了一组系统调用接口

Linux 提供了一个完整的操作系统中,最底层的硬件控制和资源管理的完整架构,这个是沿用Unix而来的,相当稳定且强大

Linux distributions

linux 是操作系统最底层的内核以及其提供的内核管理工具,任何都可以获取源码并执行这个内核程序

随着Linux使用者逐渐增多,可以在Linux上运行的软件也越来越多,Linux + 各种软件 就可以是一个相当完整的操作系统

为了让用户可以接触到Linux,有人将 Linux 与可运行的软件集成起来,加上 一个可以让用户以光盘或者网络直接安装或者管理Linux系统,我们称这一整套 可完全安装的系统为 Linux distribution --- 可完全安装套件

常见的几个 Linux distribution

red hat - 红帽子

ubuntu -- 无班图

centos

Linux distribution 使用的都是 www.kernel.org 中提供的Linux内核,各家使用的软件大同小异,最大的差别在于软件的安装模式

查看当前是什么 distribution

lsb_release -a
chapter 3

每一个组件或者设备在Linux下都是一个文件

磁盘

主要有 盘片 机械手臂 主轴马达组成

分区

最简单的分区: 区分根目录 与内存交换空间 swap 即可

稍微麻烦一点:将一些读写频繁的重要目录,与根目录独立出来,比如 /, /usr, /var 等

chapter4

内存交换空间是指?

当有数据被存放在物理内存中,但是这些数据不是常被CPU所取用,那么这些不常被使用的程序将会被丢到硬盘的swap交换空间中,而将速度较快的物理内存空间释放出来给真正需要的程序使用

所以如果系统不忙,内存又打,就不需要swap了

chapter 5 基础 命令的格式
commond [option]

区分大小写

按下enter之后开始执行命令

一些简单的命令
命令 含义
date 获取日期
cal 获取日历
bc 进入计算器模式

cal

只是输入 cal 是展示当前月份的日历

cal // 当前月份
cal 2018 // 2018的所有月
cal 8 2018 // 2018 8月

bc 进入计算器模式

输入 quit 然后回车 可以自动退出计算器模式

重要的按键

tab 命令补齐 和 文件名补齐

ctr + c 终止当前命令

Linux在线求助 man page

比如想查看关于date 命令的一些信息

man date

看下第一行这里是个 DATE(1)

这里的数字含义是 (这里列几个常见的)

数字 含义
1 用户在shell环境中可操作的命令或者更可执行的文件
4 设备文件
5 配置文件或者是某些文件的格式
8 系统管理员可用的管理命令
Linux在线求助 info page

另外一种在线求助命令 info page

基础命令

关机 shutdown

数据同步写入硬盘 sync

重启 reboot halt poweroff

数据在计算机中运行的模式: 所有的数据都得要被读入内存后才能够被CPU所处理,但是数据又常常需要由内存写回硬盘当中(例如储存的动作)。 由于硬盘的速度太慢(相对于内存来说),如果常常让数据在内存与硬盘中来回写入/读出,系统的效能就不会太好

因此在Linux系统中,为了加快数据的读取速度,所以在默认的情况中, 某些已经加载内存中的数据将不会直接被写回硬盘,而是先缓存在内存当中,如此一来, 如果一个数据被你重复的改写,那么由于他尚未被写入硬盘中,因此可以直接由内存当中读取出来, 在速度上一定是快上相当多的!

不过,如此一来也造成些许的困扰,那就是万一你的系统因为某些特殊情况造成不正常关机 (例如停电或者是不小心踢到power)时,由于数据尚未被写入硬盘当中,会造成数据不正常啦! 那要怎么办呢?这个时候就需要sync这个命令来进行数据的写入动作啦! 直接在文字接口下输入sync,那么在内存中尚未被升级的数据,就会被写入硬盘中!所以,这个命令在系统关机或重新启动之前,最好多运行几次

目前的 shutdown/reboot/halt 等等命令均已经在关机前进行了 sync 命令

chapter 6
文件权限与目录配置
三种身份

文件所有者、用户组、其他人

系统中所有的帐号与一般身份使用者,以及root的相关信息, 都是记录在/etc/passwd文件中,每个人的密码则是记录在/etc/shadow文件中,此外,所有的组群名称记录在/etc/group文件中

用户

Linux系统是一个多用户多任务的分时操作系统,任何一个要使用系统资源的用户,都必须首先向系统管理员申请一个账号,然后以这个账号的身份进入系统

用户组

每个用户都有一个用户组,系统可以对一个用户组中的所有用户进行集中管理。不同Linux 系统对用户组的规定有所不同,如Linux下的用户属于与它同名的用户组,这个用户组在创建用户时同时创建
ls -al 查看当前目录下文件的信息

ls 显示文件的文件名和相关属性

al 列出文件详细的权限的属性

-rw-r--r--   1 zhengzaijiazai  staff       66  4 25 10:21 .gitignore
drwxr-xr-x   2 zhengzaijiazai  staff       68  4 25 11:32 dist

drwxr-xr-x

d rwx r-x r-x

按照 1 3 3 3 的格式进行拆分

命令 含义
d 第一个字符 代表这个是目录 文件 或者 链接文件等
rwx 文件所有者的权限
r-x 文件同用户组的权限
r-x 其他非本用户的权限

r (read)可读 w (write) 可写 x (execute)可执行

文件权限的意义 对于文件

r 代表是否能查看文件的内容
w 代表能否对文件的内容进行操作,但是不能删除文件
x 代表能否被系统执行

对于目录

目录的主要内容是记录文件名列表

r 表示可以读取目录结构列表

w 表示具有更改目录列表的权限

w权限对于文件的含义
创建新的文件与目录
删除文件和目录(不管文件权限)
将已存在的文件与目录重命名
移动文件,目录位置

总而言之,目录的w权限与该目录下的文件名变动有关系

x 表示用户能否进入目录 比如cd 进入此目录

test time

有一个目录权限为

drwxr--r-- 3 root root .......

当前系统账号为 userA userA不属于root组 那么 userA 对于这个账户有什么权限, 能切换到此目录中吗

answer

userA 具有 读的权限

而进行目录切换是需要X的权限 所以不可以切换到此目录

修改文件的属性、权限
命令 含义
chgrp xxx filename 改变文件所属用户组
chown xxx filename 改变文件所有者
chmod xxx filename 改变文件的权限
chgrp (change group)

要改的那个组必须在 /etc/group 中存在 否则会报错

chgrp read.md groupB
chown (change owner)

要改的那个用户必须在 /etc/passwd 中有记录 否则会报错

chown read.md userB
chown chmod 改变权限

使用分数

使用分数也可以代表权限

命令 分数
r 4
w 2
x 1

rwx 7
rw- 6
r-x 5

使用符号类型

有三种身份,就用 u g o 代表三种身份的权限

身份 字符
用户 u
用户组 g
其他人 o
所有身份 a
命令 含义
+ 增加
- 减去
= 设置

比如 需要设置一个文件的权限为 -rwxr-xr-x

则u 为rwx g/o 为 r-x

chmod u=rwx,go=rx readme.md
// 如果是给每一身份增加 w 权限
chmod a+w read.md
文件种类

任何设备都是文件

使用 ls -l 中第一个字符就是文件种类

分类

普通文件文件

ls -al 所显示出来的属性方面,第一个字符为 [ - ],例如 [-rwxrwxrwx ]。另外,依照文件的内容,又大略可以分为:纯文本 二进制文件 数据格式文件

目录

链接文件

比如: 快捷方式

设备与设备文件

文件扩展名

与 window中的有很大不同

在Windows底下, 能被执行的文件扩展名通常是 .com .exe .bat等等,而在Linux底下,只要你的权限当中具有x的话,例如[ -rwx-r-xr-x ] 即代表这个文件可以被执行

通常我们还是会以适当的扩展名来表示该文件是什么种类的。底下有数种常用的扩展名:

1 .sh : 脚本或批处理文件 (scripts),因为批处理文件为使用shell写成的,所以扩展名就编成 .sh ;

2 .Z, .tar, .zip : 经过打包的压缩文件。这是因为压缩软件分别为 gunzip, tar 等等的,由于不同的压缩软件,而取其相关的扩展名

3 .html, .php:网页相关文件,分别代表 HTML 语法与 PHP 语法的网页文件

基本上,Linux系统上的文件名真的只是让你了解该文件可能的用途而已, 真正的执行与否仍然需要权限的规范才行

例如虽然有一个文件为可执行文件, 如常见的/bin/ls这个显示文件属性的指令,不过,如果这个文件的权限被修改成无法执行时, 那么ls就变成不能执行

目录配置 标准 FHS

为什么每套Linux distributions他们的配置文件啊、执行文件啊、每个目录内放置的咚咚啊,其实都差不多? 原来是有一套标准依据的

Linux来开发产品或distributions的社群/公司与个人实在太多了,如果每一个人都按照自己的标准去配置文件目录,可能有管理上的困扰

FHS 用于规范每个特定目录下应该要放置什么数据

FHS针对目录树定义了三个目录下应该放置什么数据

目录 含义
/ (root 根目录) 与开机系统有关系
/usr 与软件的安装、执行有关系
/var 与系统运作过程有关系

usr (UNIX Software Resource)Unix操作系统软件资源

FHS 定义(/)根目录下需要有以下目录

目录 文件内容
/bin 执行文件,在/bin 下的命令 可以被root和一般账号使用,比如 cat cp等
/etc 系统主要配置文件,例如账号密码文件,何种服务的启示文件
/tmp 正在执行的程序放置文件的地方 FHS建议在开机时将 /tmp下的数据删除

/usr

是系统默认的软件安装目录

下面比较常见的目录

目录 文件内容
/bin 用户可使用的命令

/var

在系统安装之后,会慢慢占用硬盘容量

Q: 请问在 /bin 与 /usr/bin 有什么不同

A:

/bin是系统的一些指令

bin为binary的简写主要放置一些系统的必备执行档例如:cat、cp、chmod df、dmesg、gzip、kill、ls、mkdir、more、mount、rm、su、tar等

/usr/bin 是你在后期安装的一些软件的运行脚本

主要放置一些应用软体工具的必备执行档例如c++、g++、gcc、chdrv、diff、dig、du、eject、elm、free、gnome、 gzip、htpasswd、kfm、ktop、last、less、locale、m4、make、man、mcopy、ncftp、 newaliases、nslookup passwd、quota、smb、wget等

绝对路径与相对路径

绝对路径

由根目录开始写起的文件名或者目录

相对路径

相对于当前路径

~ 代表当前用户的家目录 或者 使用cd 回车 也可以进入

/ 代表根目录

chapter 7 目录相关 特殊的目录
标志 含义
. 本层目录
.. 上一层目录
- 前一个工作目录

Q: 请问在Linux的根目录,有没有上层目录 (..) 的存在

A:

用普通用户身份看下

用root身份看一下

操作文件与目录
命令 含义
cd 切换目录 change directory
pwd 显示当前目录
mkdir 创建新目录
rmdir 删除空目录
cp 复制
mv 移动 重命名文件与目录

创建目录 mkdir

mkdir 只能一层一层的创建目录, 如何一次性创建多层目录 -- 借助 -p 参数

mkdir -p webpack/w1-code/dist

删除目录

rmdir config

只能删除一个空目录

如果要强制删除一个非空目录及它下面的全部

rm -r node_modules

查看目录

ls -a // 显示全部,连同隐藏的文件

mv

// 将某一个文件移动到文件夹中
mv mian.js newdir
// 重命名文件夹
mv oldDir newdir

cp 复制

复制文件需要有 r (可读) 权限

// 复制index 文件到 当前位置
cp ./config/index.js .

默认条件中,cp的源文件与目的文件权限不同,目的文件的所有者是命令操作者本身

查阅文件内容 file 查询文件类型

判断文件是二进制文件?数据文件?

which

查询命令所在的文件

which ifconfig

which 默认查找的是 PATH 内的目录

cat (Concatenate 连续)
命令 含义
cat 查看内容
cat -n 查看内容 显示行号
cat -b 查看内容 显示行号 【空白部分不算行号】
nl 添加行号打印

nl 可以将输出的内容自动加上行号 默认结果与cat -n有点类似

nl [-bnw] filename

-b 命令 含义
a 空行也添加行号
t 空行不添加行号
-n 命令 含义
ln 行号在左侧显示
rn 行号在右侧显示 不加0
rz 行号在右侧显示 加0
nl index.js

nl -b a index.js 空行也添加行号
more

前面提到的nl cat 是一次性将所有内容展示到命令行 more 则是 有翻页功能

more index.js
-n 命令 含义
空格 向下翻一页
enter 或者 向下键 向下滚动一行
q 退出显示

查找功能

按下 / 然后输入 要查找的字符 [但是没有发现有任何高亮提示]

less

less 的用法要比more 增加了向上翻页功能

less index.js

查找功能

按下 / 然后输入 要查找的字符 [向下查询]
按下 ? 然后输入 要查找的字符 [向上查询]

选择数据 head tail

head 从前面开始展示

选取数据展示几行

head [-n number] filename

number 表示展示几行 默认展示前10行

tail 从后面开始展示

tail [-n number] filename

number 表示展示几行 默认展示最后10行

获取第 100 到 120 行

cat filename | head -n 120 | tail -n +100

从 100 行开始 显示 50行

cat filename | tail -n +100 | head -n 50

tail -n +100:从100行开始显示,显示100行以后的

文件的权限预设 umask

当新建一个文件时,它的默认权限和umask有关系

umask是用来指定当前用户在新建目录或文件时的权限预设值,具体来说,umask值只是一个掩码,它从创建文件时的默认权限中掩去对应位置的权限

0022 以数字形式表示权限

可以看到这里有四组权限,第一组是特殊权限使用的,我们平时只需要后面三个就可以了

u=rwx 以符号类型表示权限

在默认权限的属性,文件和目录是不同的

用户创建一般文件,则默认取消可执行权限,即666(rw-rw-rw-)

用户创建目录文件,由于x与是否可以进入此目录有关,因此默认开放所有权限,即777(rwxrwxrwx)

Q: 假设用户的umask是 003 则当其新建一个文件或者文件夹 的权限是什么

A: 也就是去掉的权限是 other的 写 w 与 x

文件 rw-rw-r--

文件夹 rwxrxwr--

设置 umask

umask 002
查询文件 find
find [指定路径] [指定条件] [指定动作]

默认会查找当前目录及子目录,把查找结果输出到屏幕上

touch

关于文件的三个时间参数

modification time (mtime): 当该文件的『内容数据』变更时,就会升级这个时间!内容数据指的是文件的内容,而不是文件的属性或权限

status time (ctime):当该文件的『状态 (status)』改变时,就会升级这个时间,举例来说,像是权限与属性被更改了,都会升级这个时间

access time (atime):当『该文件的内容被取用』时,就会升级这个读取时间 (access)。举例来说,我们使用 cat 去读取 /etc/man.config , 就会升级该文件的 atime

在默认的情况下,ls 显示出来的是该文件的 mtime ,也就是这个文件的内容上次被更动的时间

ls -l —time=ctime test.conf
权限和文件的关系

![important]](https://user-gold-cdn.xitu.io...

用户能进入某目录成为可工作目录的基本权限是什么

条件 内容
可使用命令 cd等切换工作目录
目录所需权限 x 要有可执行的权限

用户在某一个目录可以读取一个文件的基本权限是什么

条件 内容
可使用命令 cat more less tail head 等
目录所需权限 x 要有可执行的权限
文件所需权限 r 要有可读的权限

让用户修改一个文件的权限是什么

条件 内容
可使用命令 vi vim 等
目录所需权限 x 要有可执行的权限
文件所需权限 r w 要有可读可写的权限

让用户新建一个文件的基本权限是什么

条件 内容
可使用命令 touch 等
目录所需权限 w x 要有可读可执行的权限
$PATH

为什么在任何地方都可以执行 ls 这个命令呢 -- 环境变量 PATH

系统会依照PATH的设置去每个定义PATH的目录下查询文件名为ls的可执行文件,如果在PATH定义的目录中含有多个文件名为ls的可执行文件,那么先查询的同名命令则先被执行

1 ls 是一个可执行文件
2 根源在 /bin/ls (也就是执行ls 与执行 /bin/ls 是同样的效果)
3 问题变为,为什么随时可以执行 /bin/ls 这个文件
4 系统按照 PATH 的设置每一个 path的定义目录下 查询名为ls的可执行文件
5 先找到的被执行

不同身份的 默认的path 不同,默认能够随意运行的命令也不同(如root与vbird)

PATH是可以修改的

chapter 8 磁盘和文件管理

EXT2

Linux最传统的磁盘文件系统(filesystem)使用的是EXT2

磁盘分区指的是告诉操作系统 这个磁盘在此分割槽可以存取的区域是由 A 磁柱到 B 磁柱之间的区块

如此一来操作系统就能够知道他可以在所指定的区块内进行文件数据的读/写/搜寻等动作了。 也就是说,磁盘分区意即指定分割槽的启始与结束磁柱

文件系统

磁盘在做分区之后还需要格式化,这是因为每种操作系统所配置的文件属性/权限并不相同, 为了存放这些文件所需的数据,因此就需要将分区进行格式化,以成为操作系统能够利用的文件系统格式

文件系统的运行

这与操作系统的文件数据有关。较新的操作系统的文件数据除了文件实际内容外, 通常含有非常多的属性

例如 Linux 操作系统的文件权限(rwx)与文件属性(拥有者、群组、时间参数等)。 文件系统通常会将这两部份的数据分别存放在不同的区块,权限与属性放置到 inode 中,至于实际数据则放置到 data block 区块中

另外,还有一个超级区块 (superblock) 会记录整个文件系统的整体信息,包括 inode 与 block 的总量、使用量、剩余量等

属性 含义
inode 记录文件的属性,一个文件占用一个inode,同时记录此文件的数据所在的 block 号码
block 实际记录文件的内容,若文件太大时,会占用多个 block
superblock 记录此 filesystem 的整体信息,包括inode/block的总量、使用量、剩余量, 以及文件系统的格式与相关信息等

inode

inode 的内容在记录文件的权限与相关属性,至于 block 区块则是在记录文件的实际内容

而文件系统一开始就将 inode 与 block 规划好了,除非重新格式化,否则 inode 与 block 固定后就不再变动

Ext2 文件系统在格式化的时候基本上是区分为多个区块群组 (block group) 的,每个区块群组都有独立的 inode/block/superblock 系统

block

data block 是用来放置文件内容数据地方,在 Ext2 文件系统中所支持的 block 大小有 1K, 2K 及 4K 三种而已。在格式化时 block 的大小就固定了

1 原则上,block 的大小与数量在格式化完就不能够再改变了(除非重新格式化)
2 每个 block 内最多只能够放置一个文件的数据
3 承上,如果文件大于 block 的大小,则一个文件会占用多个 block 数量
4 承上,若文件小于 block ,则该 block 的剩余容量就不能够再被使用了(磁盘空间会浪费)

Q: 假设你的Ext2文件系统使用 4KB de block ,而该文件系统中有 10000 个小文件,每个文件大小均为 50 bytes, 请问此时你的磁盘浪费多少容量?

A:

4kb = 4 * 1024 bytes = 4096 bytes

所以每一个会浪费 4096 - 50 bytes

所以公共会是 4046 * 10000 bytes = 38.585666 = 38.6MB

与目录树的关系

文件目录

当我们在 Linux 下的 ext2 文件系统创建一个目录时, ext2 会分配一个 inode 与至少一块 block 给该目录

其中,inode 记录该目录的相关权限与属性,并可记录分配到的那块 block 号码

而 block 则是记录在这个目录下的文件名与该文件名占用的 inode 号码数据

文件

当我们在 Linux 下的 ext2 创建一个一般文件时, ext2 会分配一个 inode 与相对于该文件大小的 block 数量给该文件

例如:假设我的一个 block 为 4 Kbytes ,而我要创建一个 100 KBytes 的文件,那么 linux 将分配一个 inode 与 25 个 block 来储存该文件

inode 本身并不记录文件名,文件名的记录是在目录的 block 当中。 因此在第六章文件与目录的权限说明中, 我们才会提到『新增/删除/更名文件名与目录的 w 权限有关』

因为文件名是记录在目录的 block 当中, 因此当我们要读取某个文件时,就务必会经过目录的 inode 与 block ,然后才能够找到那个待读取文件的 inode 号码, 最终才会读到正确的文件的 block 内的数据

文件系统的操作

所有的数据都得要加载到内存后 CPU 才能够对该数据进行处理

想一想,如果你常常编辑一个好大的文件, 在编辑的过程中又频繁的要系统来写入到磁盘中,由于磁盘写入的速度要比内存慢很多, 因此你会常常耗在等待硬盘的写入/读取上

为了解决这个效率的问题, Linux 使用的方式是透过一个称为异步处理 (asynchronously) 的方式

当系统加载一个文件到内存后,如果该文件没有被更动过,则在内存区段的文件数据会被配置为干净(clean)的。 但如果内存中的文件数据被更改过了(例如你用 nano 去编辑过这个文件),此时该内存中的数据会被配置为脏的 (Dirty)。此时所有的动作都还在内存中运行,并没有写入到磁盘中! 系统会不定时的将内存中配置为『Dirty』的数据写回磁盘,以保持磁盘与内存数据的一致性

由于内存的速度要比硬盘快的多,因此如果能够将常用的文件放置到内存当中,这样就会大大提升系统性能

Linux 系统上面文件系统与内存有非常大的关系:

1 系统会将常用的文件数据放置到主存储器的缓冲区,以加速文件系统的读/写
2 承上,因此 Linux 的物理内存最后都会被用光!这是正常的情况!可加速系统效能
3 你可以手动使用 sync 来强迫内存中配置为 Dirty 的文件回写到磁盘中
4 若正常关机时,关机命令会主动呼叫 sync 来将内存的数据回写入磁盘内
5 不正常关机(如跳电、死机或其他不明原因),由于数据尚未回写到磁盘内, 因此重新启动后可能会花很多时间在进行磁盘检验,甚至可能导致文件系统的损毁(非磁盘损毁)

挂载

文件系统与目录树的结合操作称之为挂载 挂载点一定是目录 这样才能使用文件系统

磁盘和目录容量

磁盘的整体数据是在 superblock 区块中,但是每个各别文件的容量则在 inode 当中记载的

命令 含义
df 列出文件系统的整体磁盘使用量
du 评估文件系统的磁盘使用量(常用在推估目录所占容量)

df

由于 df 主要读取的数据几乎都是针对一整个文件系统,因此读取的范围主要是在 Superblock 内的信息, 所以这个命令显示结果的速度非常的快速

du

与 df 不一样的是,du 这个命令其实会直接到文件系统内去搜寻所有的文件数据

在默认的情况下,容量的输出是以 KB 来设计的, 如果你想要知道目录占了多少 MB ,那么就使用 -m 这个参数即可

连接文件 hard id_link

新建一个文件名 链接到 某个inode 号码

symbolic link

Symbolic link 就是在创建一个独立的文件,而这个文件会让数据的读取指向他 link 的那个文件的文件名

ln [-sf] 源文件 目标文件

// 不添加参数就是 hard link
// 添加参数 -s 就是 symbolic link

// f 如果目标文件存在 则先删除后再创建
chapter 10 vim 编辑器

vi 文本编辑器 vim 程序开发工具

vi

vi 共分为三种模式,分别是『一般模式』、『编辑模式』与『指令列命令模式』

一般模式

以 vi 打开一个档案就直接进入一般模式了(这是默认的模式)

编辑模式

一般模式当中, 按下『i, I, o, O, a, A, r, R』等任何一个字母之后会进入编辑模式

指令列命令模式

一般模式当中,输入『 : / ? 』三个中的任何一个按钮,就可以将光标移动到最底下那一行

chapter 11 bash

shell

需要计算机输出音乐,这个过程需要什么支持呢

1 硬件

需要你的硬件有声卡芯片

2 内核管理

需要操作系统的内核可以支持这个芯片组 还有芯片的驱动程序

3 应用程序

需要用户输入播放声音的指令

以上三点是一个简单的输出声音的步骤。就是用户需要输出一个命令,硬件才会执行这个命令来工作。而硬件如何知道你所执行的命令呢,那就是内核的控制工作了

我们需要通过shell将输入的命令与内核进行通信,这样内核就可以控制硬件来工作

操作系统是一组软件,这组软件在控制硬件与管理系统的活动监测。如果这组软件能被用户随意操作会导致系统崩溃。

所以不能让用户随意去使用。因此产生了一种在操作系统上的应用程序->shell

其实shell的功能只是提供用户操作系统的一个接口,因此这个shell需要可以调用其他软件。

简而言之,只要能够操作应用程序的接口,都叫做shell
Linux的shell

Linux有多种shell, 可以看下 /etc/shells

各家的shell功能差不多,但是在某些语法执行方面不同。

Linux默认使用的是 bash

为什么我们系统上合法的 shell 要写入 /etc/shells 这个文件啊? 这是因为系统某些服务在运行过程中,会去检查使用者能够使用的 shells ,而这些 shell 的查询就是藉由 /etc/shells 这个文件

我这个使用者什么时候可以取得 shell 来工作呢?还有, 我这个使用者默认会取得哪一个 shell ?

当我登陆的时候,系统就会给我一个 shell 让我来工作了。 而这个登陆取得的 shell 就记录在 /etc/passwd 这个文件内

bash

bash 的几个优点

1 命令记忆功能

『上下键』可以追溯命令

~/.bash_history 记录的是前一次登陆以前所运行过的命令, 而至于这一次登陆所运行的命令都被缓存在内存中,当你成功的注销系统后,该命令记忆才会记录到 .bash_history 当中

2 命令与文件补全功能

tab 键

3 命名别名设置功能

查询 alias

设置 alias lm=‘ls -al’

4 作业控制,前台,后台控制

5 程序脚本

当登录到Linux后,会依据/etc/passwd 文件的设置来给一个shell(默认bash) 然后就可以依据上面的命令操作 shell

type

内部命令:由 bash 内置的命令

外部命令:来字外部的命令,非 bash 内置

查询一个命令是外部的还是bash内置的呢? -- type

可以看到 cd 这个命令是bash的内置命令

shell 的变量功能

Linux是多用户,多任务的环境,每个人在登录之后都会有一个bash。

显示当前使用的shell,可以输入:

echo $SHELL

影响bash环境变量的操作

那么由于在 Linux System 下面,所有的线程都是需要一个运行码, 『真正以 shell 来跟 Linux 沟通,是在正确的登陆 Linux 之后』这个时候你就有一个 bash 的运行程序,也才可以真正的经由 bash 来跟系统沟通

而在进入 shell 之前,也正如同上面提到的,由于系统需要一些变量来提供他数据的存取 (或者是一些环境的配置参数值, 例如是否要显示彩色等等的) ,所以就有一些所谓的『环境变量』 需要来读入系统中了!这些环境变量例如 PATH、HOME、MAIL、SHELL 等等

读取变量

变量在显示的时候,前面必须带着 $ 符号

echo $PATH
echo ${PATH}
cd $work
设置变量
workdir="workapce/mxx"
变量的设置规则
变量名称只能是字母与数字,但开头不能为数字
双引号内的特殊字符可以保留原特性,比如$ 可正确读取字符串中的变量,单引号则不会
name="my name is $USER"
echo $name
// mu name is tom

name="my name is $USER"
echo $name
// mu name is $USER
取消变量
unset workdir

Q: 设置一个 变量代表 工作目录


在父进程中定义的变量是无法在子进程中使用的,比如你定义了这个变量,然后再重新发开一个进程,是读不到这个变量的

不过通过export将此变量设置为环境变量就可以使用了

比如,定义变量 TRYPATH=/HOME/EORK

写一个脚本

echo $TRYPATH, 123

然后在当前进程中执行 sh test.sh

控制台无输出

如果 export TRYPATH=/HOME/EORK

就有信息输出了

环境变量的功能

查询当前有哪些环境变量,可以使用两个命令 env export

env

查询到目前shell环境下所有的环境变量

set

shell不只是有环境变量,还有各种自定义的变量

set查询所有的变量

export

环境变量和自定义变量两者的差异在于 是否可以被子进程使用

子进程会继承父级进程的环境变量,不会继承父进程的自定义变量

export 可以将自定义变量转为环境变量

export

// export WORKDIR=$WORKDIR:workspace/blued-shopping/blued-shop

可以看到目前所有的环境变量

父进程?子进程?

当你登陆 Linux 并取得一个 bash 之后,你的 bash 就是一个独立的程序,被称为 PID 的就是。 接下来你在这个 bash 底下所下达的任何命令都是由这个 bash 所衍生出来的,那些被下达的命令就被称为子程序了。

为什么子进程可以使用环境变量

1 当创建一个shell时候,操作系统会分配一个记忆块给shell使用,此内存的变量可以给子进程使用

2 在父进程使用了 export ,就可以将自定义的变量写到上面的那个记忆块中

3 当加载另一个shell的时候(启动子进程,要离开父进程了)子shell可以将父shell的那个记忆块导入自己的环境变量块中

ulimit

Linux 主机里面同时登陆了十个人,这十个人不知怎么搞的, 同时开启了 100 个文件,每个文件的大小约 10MBytes ,

请问一下, 我的 Linux 主机的内存要有多大才够? 1010010 = 10000 MBytes = 10GBytes ... 内存占用量很大,所以可以限制这个大小

bash 可以限制用户的某些系统资源,比如文件打开数量,可用的CPU时间,可用内存总量等 ,这些通过 ulimit 进行设置

参数解析 含义
unlimited 无限制
0 无限制
history

查看历史命令

history
history 10
history -w // 写入 ~./bash_history

历史命令的读取与记录是这样的:

以 bash 登陆 Linux 主机之后,系统会主动的由家目录的 ~/.bash_history 读取以前曾经下过的命令,那么 ~/.bash_history 会记录几笔数据呢?这就与你 bash 的 HISTFILESIZE 这个变量配置值有关了!

假设我这次登陆主机后,共下达过 100 次命令,『等我注销时, 系统就会将 101~1100 这总共 1000 笔历史命令升级到 ~/.bash_history 当中。』 也就是说,历史命令在我注销时,会将最近的 HISTFILESIZE 笔记录到我的纪录文件当中啦!

当然,也可以用 history -w 强制立刻写入的!那为何用『升级』两个字呢? 因为 ~/.bash_history 记录的笔数永远都是 HISTFILESIZE 那么多,旧的信息会被主动的拿掉! 仅保留最新的!

bash的操作环境 路径和命令的查找顺序

在我们系统中存在多个名字相同的名字,那么 bash shell 究竟使用的是哪个命令呢?其遵循的顺序如下

1.以相对/绝对路径来执行命令
2.由 alias 找到命令来执行
3.由 bash 内置命令来执行
4.通过$PATH 的顺序找到的第一个命令来执行

[root@localhost ~]# alias echo="echo -n"
[root@localhost ~]# type -a echo
echo is aliased to `echo -n"
echo is a shell builtin
echo is /bin/echo

可以看到先找alias在内置命令 最后PATH

bash的登录信息

这些都可以进行配置的

shell 的配置文件

怎么我们什么动作都没有进行,但是一进入 bash 就取得一堆有用的变量了?

这是因为系统有一些环境配置文件案的存在,让 bash 在启动时直接读取这些配置文件,以规划好 bash 的操作环境

这些配置文件又可以分为全体系统的配置文件以及用户个人偏好配置文件。

我们前几个小节谈到的命令别名啦、自定义的变量啦,在你注销 bash 后就会失效,所以你想要保留你的配置, 就得要将这些配置写入配置文件才行。

Bash 配置文件

以 login shell 方式

1 /etc/profile 系统最主要的shell配置文件,每次login,bash都要读取 /etc/profile文件

PATH:会依据 UID 决定 PATH 变量要不要含有 sbin 的系统命令目录;
MAIL:依据账号配置好使用者的 mailbox 到 /var/spool/mail/账号名;
USER:根据用户的账号配置此一变量内容;
HOSTNAME:依据主机的 hostname 命令决定此一变量内容;
HISTSIZE:历史命令记录数

2 个人配置文件

bash 在读完了整体环境配置的 /etc/profile 以及其他配置文件后,接下来则是会读取使用者的个人配置文件

其实 bash 的 login shell 配置只会读取上面三个文件的其中一个, 而读取的顺序则是依照上面的顺序。也就是说,如果 ~/.bash_profile 存在,那么其他两个文件不论有无存在,都不会被读取。 如果 ~/.bash_profile 不存在才会去读取 ~/.bash_login,而前两者都不存在才会读取 ~/.profile 的意思

在 login shell 的 bash 环境中,所读取的个人偏好配置文件其实主要有三个,依序分别是:

~/.bash_profile
~/.bash_login
~/.profile

~/.bash_profile 是个人的bash配置文件,存在每位用户的$HOME

~/.bash_login 用户登陆时 bash会读取这个文件。通常把登陆就要执行的指令放在这

以 non-login shell 方式

~/.bashrc 每次打开shell,shell都会读取的文件。每次打开shell,执行一次

其余的配置文件为

4 ~/.bash_logout 是退出系统时bash在退出时执行的

5 ~/.bash_history 是历史功能的记录文件

数据流重定向
数据流重定向 就是把某些要出现在屏幕上的数据传输到其他地方
数据流

输入数据流:以写文件为例,从键盘输入的字符就输入数据流

输出数据流:以读文件为例,将文件内容显示到屏幕上,显示的内容就是输出字符流

输出数据流又可分为:标准输出 标准错误输出

标准输入 < 或者 <<

标准输出 > 或者 >>

标准错误输出 2> 或者 2>>

( 一个< 表示覆盖 二个<< 表示进行追加 )

echo config.js > copy.js

本应该出现在屏幕上的所有的config的信息 会被 导入到copy.js文件

这个copy文件的创建方式为

1 该文件若不存在,系统会自动的将他创建起来

2 当这个文件存在的时候,那么系统就会先将这个文件内容清空,然后再将数据写入

也就是若以 > 输出到一个已存在的文件中,那个文件就会被覆盖掉

如果不想被覆盖,而是继续追加信息,使用 >>

命令行中的判断 && ||
ls tmp/info && touch tmp/info/a
管道

bash 命令运行的时候有输出的数据会出现! 那么如果这群数据必需要经过几道手续之后才能得到我们所想要的格式,应该如何来配置?

grep

uniq 去重

wc 统计

chapter 13 shell script

就是在 shell 上运行的 script 脚本

开发

以 #!/bin/bash 开头 用以声明文件内语法使用bash语法

条件判断

if [ 条件判断式 ]; then
    当条件判断式成立时,可以进行的命令工作内容;
fi   <==将 if 反过来写,就成为 fi 啦!结束 if 之意!
如何运行

sh base.sh
bash base.sh
/bin/bash base.sh
/bin/sh base.sh

source x.sh

source 可以回传变量

// 定义变量 export 到全局
export TRYPATH="trypath"

// 定义 test.sh 内容为  
// echo $TRYPATH
// TRYPATH="changepath"
sh test.sh  // -> trypath

echo $TRYPATH // -> trypath

// 使用source执行

source test.sh // trypath

echo $TRYPATH // -> changepath

也就是 source 可以修改父进程的变量

chapter 14 账号管理与权限设置

账号与用户组

登陆 Linux 主机的时候,输入的是我们的账号, ID 与账号的对应就在 /etc/passwd 当中

每个登陆的使用者至少都会取得两个 ID ,一个是使用者 ID (User ID ,简称 UID)、一个是群组 ID (Group ID ,简称 GID)

文件如何判别他的拥有者与群组

每一个文件都会有所谓的拥有者 ID 与拥有群组 ID ,当我们有要显示文件属性的需求时,系统会依据 /etc/passwd 与 /etc/group 的内容, 找到 UID / GID 对应的账号与组名再显示出来

在输入账号和密码登录shell时候 系统会发生什么

1 先找寻 /etc/passwd 里面是否有你输入的账号

如果没有则跳出,如果有的话则将该账号对应的 UID 与 GID (在 /etc/group 中) 读出来,另外,该账号的主文件夹与 shell 配置也一并读出

2 再来则是核对密码表啦!

这时 Linux 会进入 /etc/shadow 里面找出对应的账号与 UID,然后核对一下你刚刚输入的密码与里头的密码是否相符

3 如果一切都 OK 的话,就进入 Shell 控管的阶段

/etc/passwd

每一行都代表一个账号,有几行就代表有几个账号在你的系统中

按照 : 分为 7个部分

[用户名]:[密码]:[UID]:[GID]:[身份描述]:[主目录]:[登录shell]

/etc/shadow

我们知道很多程序的运行都与权限有关,而权限与 UID/GID 有关!因此各程序当然需要读取 /etc/passwd 来了解不同账号的权限。 因此 /etc/passwd 的权限需配置为 -rw-r--r-- 这样的情况, 虽然早期的密码也有加密过,但却放置到 /etc/passwd 的第二个字段上!这样一来很容易被有心人士所窃取的, 加密过的密码也能够透过暴力破解法去 try and error (试误) 找出来

因为这样的关系,所以后来发展出将密码移动到 /etc/shadow 这个文件分隔开来的技术

testuser:!!:17854:0:99999:7:::

[账号名称] [密码] [最近更动密码的日期] [密码不可被更动的天数] [密码需要重新变更的天数] [密码需要变更期限前的警告天数] [密码过期后的账号宽限时间(密码失效日)] [账号失效日期] [保留]

[密码]

经过编码的密码 (加密) 只会看到有一些特殊符号的字母

[最近更动密码的日期]

是以 1970 年 1 月 1 日作为 1 而累加的日期,1971 年 1 月 1 日则为 366

/etc/group

记录GID 和用户组组名对应

这个文件每一行代表一个群组

它总共分四个部分:[组名]:[密码域]:[GID]:[组员列表]

看下这三者的关系

有效用户组(effective group)与初始用户组(initial group)

每个使用者在他的 /etc/passwd 里面的第四栏有所谓的 GID,就是『初始群组 (initial group) 』。也就是说,当用户一登陆系统,立刻就拥有这个群组的相关权限

但是一个用户可以被加入到多个用户组去,比如 USERA 可以同时属于 group1 (初始用户组) 与 group2 (手动添加)

那么当这个用户在新建一个文件的时候,新文件所属组是哪一个

这个取决于当时的有效用户组

查询当前用户所属的用户组

groups

第一个输出的群组即为 有效用户组 (effective group) 了

以这个用户身份去新建一个文件,则文件的用户组就是这个 有效用户组

有效群组的切换
newgrp newGrooup

但是使用newgrp 是有限制的,那就是你想要切换的群组必须是你已经有支持的群组,也就是说,只要我的用户有支持的群组就是能够切换成为有效群组

账号管理 用户相关
// 新增一个用户
usersadd newName

// 删除一个用户
userdel newName

CentOS 系统主要会帮我们处理几个项目

1 在 /etc/passwd 里面创建一行与账号相关的数据,包括创建 UID/GID/家目录等

2 在 /etc/shadow 里面将此账号的密码相关参数填入,但是尚未有密码

3 在 /etc/group 里面加入一个与账号名称一模一样的组名

4 在 /home 底下创建一个与账号同名的目录作为用户家目录,且权限为 700

此时在 /etc/shadow 内仅会有密码参数而不会有加密过的密码数据,因此还需要使用『 passwd 账号 』来给予密码才算是完成了用户创建的流程

passwd g1

为何『 useradd vbird1 』会主动在 /home/vbird1 创建起用户的家目录?家目录内有什么数据且来自哪里?为何默认使用的是 /bin/bash 这个 shell ?为何密码字段已经都规范好了 (0:99999:7 那一串)? ---- 取决于 useradd 所使用的参考文件

 useradd -D
// GROUP=100        <==默认的群组
// HOME=/home        <==默认的家目录所在目录
// INACTIVE=-1        <==密码失效日,在 shadow 内的第 7 栏
// EXPIRE=            <==账号失效日,在 shadow 内的第 8 栏
// SHELL=/bin/bash        <==默认的 shell
// SKEL=/etc/skel        <==用户家目录的内容数据参考目录
// CREATE_MAIL_SPOOL=yes   <==是否主动帮使用者创建邮件信箱(mailbox)
用户组相关
// 新增一个用户组
groupadd newName

// 删除一个用户组  r 表示连同用户主文件夹一起删除
groupdel -r newName 

// 将用户加入到组和从组中删除
gpasswd –a 用户名  组名        //添加用户
gpasswd –d 用户名  组名        //删除用户

//  查看用户属于某组
#groups  用户名
// 新建用户加入某组
useradd –g  某组名  用户
用户组管理员设置

将 g3 设置为 girls 组的管理员, 管理员可以控制 那些账号可以 移入 移除 用户组

gpasswd -A g3 girls
设置用户密码

当忘记了密码怎么办

普通用户

root管理员处理

passwd usertest

root 忘记密码

安全模式?? 太复杂了

关于处理密码

echo 123456 | passwd --stdin testuser2

直接变更密码,不需要重复确认

关闭/打开 某一个用户密码

// 使用户密码失效
passwd -S xxx
// 使用户密码解锁
passwd -u xxx

用户的身份切换

su

su 需要新用户的密码 (如果原来的是root 切换到哪一个都不需要密码 )

原本的变量不会改变, 比如PATH变量 mail 变量 还会是之前用户的

// 使用 - 可以处理这个问题
su -

exit

退出 第二个 用户状态 恢复到原始用户环境

sudo

sudo 切换需要自己的密码,有时候还不需要

sudo 可以让你以其他用户的身份运行命令 (通常是使用 root 的身份来运行命令), 只有在 /etc/sudoers 中的用户 才可以执行此命令

将用户添加到 /etc/sudoers

visudo

添加角色

用户功能

id

查询某人或者自己的uid/gid等信息

id
// uid=1006(g1) gid=1007(girls) 组=1007(girls)
id g2
// uid=1007(g2) gid=1007(girls) 组=1007(girls)

w / who

当前谁登陆在系统上

chapter16 例行性工作 crontab

什么是例行性工作?

可以理解为node中的定时任务(node-schedule)

有两种任务性质,周期性,一次性

周期性: 比如每天要睡觉

一次性: 比如偶尔会捡到钱

at 命令用于处理 一次性 的工作

crontab 命令用于处理周期性的工作,循环工作

Linux常见的例行性工作调度

日志文件的轮替

临时文件的删除

某些软件在运行中会产生一些缓存文件,但是当这个软件关闭时,这些缓存文件可能并不会主动的被移除。

系统透过例行性工作排程运行名为 tmpwatch 的命令来删除这些缓存文件

at 一次性的工作调度

atd 用于负责处理 这些一次的工作,但是并非所有的 Linux distributions 都默认会把他打开的

/etc/init.d/atd restart

使用 at 这个命令来产生所要运行的工作,并将这个工作以文字档的方式写入 /var/spool/at/ 目录内,该工作便能等待 atd 这个服务的取用与运行了

/etc/at.allow 与 /etc/at.deny

这两个文件限制了谁有权利去调用 at

1 /etc/at.allow

写在这个文件中的使用者才能使用 at ,没有在这个文件中的使用者则不能使用 at (即使没有写在 at.deny 当中)

2 如果 /etc/at.allow 不存在,就寻找 /etc/at.deny 这个文件 凡是被写入的都不能使用at了(没有被写的就可以使用)

3 如果两个文件都不存在,那么只有 root 可以使用 at 这个命令

查询当前机器中有多少 at 的工作调度

atq

删除某一个工作调度

atrm [jobnumber]
batch

batch 就是另一种 at, 但是batch会在 CPU 工作负载 低于 0.8 的时候,才进行你所下达的工作任务

CPU 工作负载

如果某一个程序他需要一直使用 CPU 的运算功能,那么此时 CPU 的使用率可能到达 100% 但是 CPU 的工作负载则是趋近1,因为 CPU 仅负责一个工作

如果同时运行2个这样的程序 CPU 的使用率还是 100% ,但是工作负载则变成 2

crontab 用户的设置

crontab 用来处理周期性的工作,为了安全考虑,可以限制哪些身份是可以使用 crontab

/etc/cron.allow

/etc/cron.deny

当使用者使用 crontab 这个命令来创建工作排程之后,该项工作就会被纪录到 /var/spool/cron/ 里面, 而且是以帐号来作为判别

比如 dmtsai 使用 crontab 后, 他的工作会被记录到 /var/spool/cron/dmtsai 里头去

默认情况下,只要用户没有被放入 /etc/cron.deny 就可以直接执行 crontab -e 去编辑自己的例行性命令了

时间位置是五个数字 * 分别代表 分钟 小时 日期 月份 周几

编写

crontab -e

我们写一个每一分钟输出当前时间的

*/1 * * * * echo $(date) > /tmp/test.txt

查看当前用的 crontab 工作

crontab -l

重启

/bin/systemctl start crond.service
系统层级的crontab

crontab -e 是对于用户的,如果是系统的例行性任务,就需要另外处理了

需要编辑 /etc/crontab 这个文件了

cron 这个服务的最低侦测限制是『分钟』,所以『 cron 会每分钟去读取一次 /etc/crontab 与 /var/spool/cron 里面的数据内容 』,因此,只要编辑完 /etc/crontab 这个文件,并且将他储存之后,那么 cron 的配置就自动运行

手动重启crond服务

/etc/init.d/crond restart

阅读需要支付1元查看
<