0%

Linux学习笔记

本文记录了小编在学习Linux的过程中总结的常用知识点

Linux特点

Linux中一切皆文件,好比Java中一切皆对象

  1. 目录树
    Linux存在目录树,存在目录树这样的虚拟结构是为了和磁盘分区解耦,增强代码的可移植性,比如只要有两台linux系统的计算机有相同的目录树结构,就可以执行相同的程序
  2. 和Windows的区别:
    1)Windows通过%%来取变量值,而Linux通过$
    2)Windows通过;来分割PATH路径,而Linux通过:来分割PATH路径
    3)Window是图形界面,而Linux是字符串界面
  3. 文件的后缀名
    在打开文件的时候需要先指定程序再打开文件,所以Linux中文件的后缀名没有意义,但是Windows中的后缀名是有意义的,因为在Windows中打开文件的方式有两种,第一种方式是先指定程序再打开文件,第二种方式是直接双击打开文件,后者的远离原理就是根据文件后缀名先启动相应的程序,然后反过来再打开指定文件
  4. 文件描述符
    文件描述符(file descriptor)是用来描述输入输出流,其中0表示输入,1表示正常输出,2表示错误输出,类似Java中的输入输出流对象

Linux启动

  1. 计算机启动后,其中叫bias的小芯片中的代码导入内存执行,决定从磁盘还是光驱引导操作系统执行
  2. 在磁盘的0磁道上找到引导程序的分区位置之后,将程序放入内存中执行
  3. 接下来install bootloader
  4. 安装的bootloader可以读取不同格式的分区,它将kernel(内核)加到内存,触发cpu将内存一刀切成kernel(内核)空间和user(用户)空间
  5. 将目录挂载到分区,挂载后找到sbin目录
  6. 找到sbin目录下的init程序(inittab文件),将其放入内存中执行(启动用户的第一个程序init),inittab程序的最后一行配置表明操作系统以什么方式启动,其中3表示命令行,5表示图形界面,1表示single方式(使用场景是当所有人都忘记了服务器登陆密码,需要重启服务器,之后就进入了single)
  7. 紧接着调起第二个程序login
  8. 然后切换成bash(shell的实现),它是一种人机交互程序,以命令提示符的方式呈现,其中bash是shell的具体实现,shell是一个进程,分成GUI(Graphical User Interface)和CLI(Command Line Interface)两种类型

bash命令

  • type
    查看命令类型,命令分成内部命令和外部命令,外部命令的样式为命令的路径,内部命令的样式为xxx is a shell builtin,外部命令通过man来学习(可以通过yum install man man-pages安装学习手册),内部命令通过通过help来学习,外部命令的执行过程是首先在bash提供的提示符中输入字符串,然后bash在磁盘中找到相应的程序扔进内存中跑起来变成进程
  • file
    查看文件类型,外部命令的文件类型是 ELF(Executable and Linkable Format)或script(通过先启动一个进程,比如python解释器,然后反过来执行脚本)
  • echo
    打印到标准输出,相当于 Java 中的System.out.println
  • $
    取变量的值,比如查看执行命令所在路径$PATH
  • ps -fe
    进程列表,比如查看docker的进程可以通过ps -ef | grep docker
  • whereis
    定位命令位置

文件系统

根目录下文件内容

  1. /boot:引导系统启动相关的文件
  2. /dev:设备文件,除了cpu外一切IO设备都抽象成文件并放到该目录下
  3. /etc:配置文件,相当于Windows中的控制面板
  4. /libs:第三方扩展程序
  5. /bin:可执行文件
  6. /var:产生的数据文件
  7. /home:普通用户的家目录,每一个用户的家目录通常默认为/home/USERNAME
  8. /root:管理员的家目录
  9. /opt:第三方程序的安装目录
  10. /usr:内部结构和当前结构类似

文件操作命令

  1. df:显示磁盘使用情况
    比如:df -h 查看磁盘信息和挂载信息( df 相当于进入了 window 中“我的电脑”,-h表示以人类可视化的方式)

  2. du:显示文件系统使用情况
    比如:du -sh 统计每个目录所占的总空间信息

  3. ls:显示目录
    比如:ls -hl 以长列表的形式可视化当前目录下的文件名以及带单位的文件大小

    第1列是文件类型+权限

    | 文件类型 | 描述 |
    | ———————— | —————————————————————————————— |
    | - | 文本,mp3,mp4等类型 |
    | d(directory) | 目录 |
    | b(block) | 块设备文件/字节流文件,一般是IO类型设备,比如磁盘 |
    | c(character) | 字符设备文件/字符流文件(在字节流上增加了编码格式,即存在规则控制),一般是IO类型设备,比如屏幕和键盘就是字符流文件,因为屏幕呈现的图像是由取值从0到255的三原色合成的像素构成,三原色需要同时打在屏幕上体现了规则控制,键盘有快捷键绑定也体现了规则控制 |
    | p(pipe) | 命令管道文件 |
    | s(socket) | 套接字类型文件,比如将百度服务器,即文件读入到本地 |

    权限共9位,每3位一组,共3组(User,Group,Other),每一组的权限有rwx(读,写,执行)

    第2列是文件硬链接的次数

    第3列是文件的属主(owner)

    第4列是文件的属组(group)

    第5列是文件大小(size),单位是字节

    第6列是时间戳(timestamp):最近一次被修改的时间

    第7列是访问时间(access)

    第8列是文件内容修改的时间(modify)

    第9列是metadata修改时间(change)

  4. cd:切换工作目录
    1)cd/cd ~:进入家目录,这里面涉及到~扩展,比如bash执行~/god会首先将其变成/home/god然后执行
    2)cd ..:进入上一级目录
    3)cd /:进入根目录
    4)cd -:进入上一次目录

  5. pwd:显示当前工作目录

  6. mkdir:创建目录
    1)mkdir -p ./a/b/c:创建多层目录
    2)–mkdir a/{1,2,3}dir:创建多个同级目录(Linux对空白符特别敏感,每条Linux指令的第一部分就是某个程序,因此千万不要夹杂空白符,否则bash会根据空白符号进行分割)

  7. rm:删除

  8. cp:拷贝
    1)cp /etc/{profile,inittab} ./:将profile,inittab文件同时拷贝到当前目录下
    2)cp -r ./a ./new:当前目录下的a文件拷贝一份成new

  9. mv:移动

  10. ln:链接
    1) ln /xxx/xx/xx.txt 硬连接名:硬连接(默认),和原文件的磁盘索引相同,删除了原文件,硬连接的内容还在
    2)ln -s /xxx/xx/xx.txt 软连接名 :软连接,和原文件文件对应的磁盘索引不同,若删除了原文件,那软连接的内容也不见了,如果创建了和原文件名称一样的新文件,那软连接的内容会更新成新文件的内容

  11. stat:查看元数据,其中Linux中文件的元数据就是windows系统中的属性,可以查看到文件的访问时间(access time),内容修改时间(modify time),元数据修改时间(change time)

  12. touch:创建新文件或将已有文件统一访问时间(access time),内容修改时间(modify time)以及元数据修改时间(change time) ,touch对已有文件作用可以应用于异地备份或者断网

文本操作命令

  1. cat:查看全文并退出,是外部命令,下面指令为类似的查看操作
    1)more:分页形式,最后退出,一般用在没有滚动条的服务器端,可以用空格和B来控制向下和向上翻页
    2)less:分页形式,最后不退出
    3)head -2 xxx.txt:查看开头2行
    4)tail -2 xxx.txt:查看末尾2行
  2. |:管道,将前面的输出不打印而是传到后面的指令,它可以和后面的指令合并
    1)cat b.txt | head -3:将b.txt中的前3行打印出来
    2)head -3 b.txt | tail -1:将b.txt中的第3行打印出来
    3)echo "/" |xargs ls -l:显示根目录下的文件信息,其中不能使用echo "/" |ls -l查询根目录,因为ls读取接受标准输入中的内容,即不能读取文件内容,所以这种管道用法对ls无效,而xargs是可以在标准输入中读取到内容,xargs将自己的参数理解成字符串,然后模仿shell做split,将第一个子字符串理解为命令,然后将分割后的第2个子字符串进行拼接和之前读取的内容进行拼接执行
  3. cut:对文本内容进行切割
    1)-d:自定义分隔符,比如-d' '表示按照空格进行切割
    2)-s:不显示没有分隔符的行
    3)-f:选择显示的列,比如-f1,3表示显示第一列和第三列
  4. sort:对文本内容进行排序,排序分成字典序(默认)和数值序
    1)-n:按照数值排序
    2)-r:倒序排列,比如-nr就是按照数值进行倒序排列
    3)-t:自定义分隔符,比如-t' '是按照空格进行切割
    4)-k:选择排序列,比如-k2是按照第2列进行排序,-k1,3, -k1-3等表示指定多列进行排序,sort -t' ' -k2 -n xxx.txt表示按照空格进行分割,针对第二列按照数值进行排序
    5)-u:合并相同行
    6)-f:忽略大小写
  5. wc:计算文本行数,常用于断点测试,断点测试分成两种,第一种是通过手动监控,可以用wc来判断数据是否完成导入,比如通过cat xxx.txt | wc -l来输出文本的行数,第二种是自动监控,比如监控生成_success数据是否完成导入

VI编辑器

VI是一款全凭的文本编辑器,在Linux系统中用VI文本编辑器编辑的文本保存之后,默认是utif-8格式,其中1个字母要开辟一个字节的内存空间,1个汉字要开辟3个字节的空间。最基础的编码格式是ascii编码,但是由于ascii编码包含的内容少,所有后来又有了扩展字符集。接下来简单介绍一下用VI编辑器编辑的文件模式以及模式之间的相互转换

文件模式

编辑模式

默认打开文件进入编辑模式,常用指令

1)h/j/k/l:分别将光标移到左下上右
2)w/e:将光标移到下一个单词的词首/词尾
3) b:将光标移到当前/前一个单词的词首
4)0/^:将光标移到行首/行首的第一个非空白字符
5)$:将光标移到行尾
6)gg:将光标移动到文章开头
7) G/nG:将光标移动到文章结尾/文章第n行
8)x:删除光标位置字符,比如3x表示删除光标开始的3个字符
9)r:替换光标位置字符
10)dd:删除/剪切光标所在行,比如3dd表示删除/剪切包括光标所在行的下三行
11)yy:复制光标所在行,比如ydd表示复制包括光标所在行的下三行
12) p:粘贴
13)u:撤销

输入模式

可以正常输入按键内容的模式

末行模式

接受用户命令输入

1):set nu:展示行数
2):set nonu:不展示行数

模式转换

  1. 编辑模式转输入模式

    1)i: 在当前光标所在字符的前面,转为输入模式
    2)a: 在当前光标所在字符的后面,转为输入模式
    3)o: 在当前光标所在行的下方新建一行,并转为输入模式
    4)O:在当前光标所在行的上方,新建一行,并转为输入模式
    5)I:在当前光标所在行的行首,转换为输入模式
    6)A:在当前光标所在行的行尾,转换为输入模式

  2. 编辑模式/输入模式转末行模式

  3. 末行模式转编辑模式

    ESC

文件打开

  1. vim /path/xxx.txt:打开path路径下的xxx.txt
  2. vim + xxx.txt:打开xxx.txt,定位至最后一行
  3. vim +n xxx.txt:打开xxx.txt,并定位于第n行
  4. vim +/PATTERN xxx.txt:打开xxx.txt,定位至第一次被PATTERN匹配到的行的行首

文件关闭

  1. :q: 退出,没有动过文件
  2. :wq:保存并退出 ,动过了不后悔
  3. q!:退出不保存,用于动过但后悔了
  4. :w :保存
  5. :w!:强行保存
  6. shit+ZZ:在编辑模式中直接保存并退出,不需要冒号(末行模式)

字符匹配

在终端我们可以通过通配符进行匹配文件或者文件名,比如*表示任意长的任意字符,?表示任意一个字符。在这一部分主要介绍一下字符匹配,字符匹配分为静态匹配和动态匹配,静态匹配也叫绝对匹配,比如匹配一个具体的字符串,动态匹配也就是用正则表达式进行匹配,其中正则表达式的操作符分为以下两种

匹配操作符

  1. \:转义字符
  2. .:匹配任意单个字符
  3. [0-7],[^5],[a-k],[123kb]:匹配其中的存在一个字符
  4. ^:行首
  5. $:行尾
  6. \<\>:匹配单词的首尾边界,比如\<abc就是匹配单词abc的开头
  7. :连接操作符(基本操作符)
  8. (,):选择操作符(基本操作符)
  9. \n:反向引用(基本操作符)

重复操作符

  1. *:匹配前面的字符0至多个
  2. :匹配前面的字符0至1个(基本操作符)
  3. +:匹配前面的字符1至多个(基本操作符)
  4. {n}:匹配n次(基本操作符)
  5. {n,}:匹配n到多次(基本操作符)
  6. {n,m}:匹配n到m次(基本操作符)

补充

  • .*就是匹配任意长度的任意字符,相当于通配符中的*
  • grep仅支持基本正则表达式以及转义的正则表达式

用户资源与权限

用户,资源(文件,目录或者程序)以及权限之间相互绑定才有意义,单说任意一项都没有意义,接下来通过举例子来简单介绍用户,资源与权限

添加用户

有一台服务器以及两个部门,现在需要添加两个用户hn01和hn02

# 普通用户只能用passwd修改自己的密码,root用户可以用passwd修改别人的密码

# 增加用户hn01(删除用户用userdel)
useradd hn01

# 由于服务器的安全级别高,每个新增用户必须新添加密码
passwd hn01

# 输入密码,密码不能是回文,字符长度不能小于8
xxxxxxxx

# 增加用户hn02
useradd hn02

# 由于服务器的安全级别高,每个新增用户必须新添加密码
passwd hn02

# 输入密码,密码不能是回文,字符长度不能小于8
xxxxxxxx

# 通过id 用户名可以查看用户id(名称) ,初始组id(名称),以及所有的组groups(名称)
id hn01

之后就可以在/home/下看到两个用户名称

用户共享文件夹

将之前新增加的两个用户共享一个文件夹用于工作交流

# 1. 在根目录下创建一个share文件夹
mkdir share
# 创建后可以发现share的属主和属组都是root

# 2. 创建一个虚拟的组hngroup(删除组用groupdel)
groupadd hngroup

# 3. 将share的属组更改成刚创建的hngroup
chown root:hngroup share

# 4. 将两个用户添加到新建的hngroup里面(相当于修改用户的元信息)
usermod -a -G hngroup hn01
usermod -a -G hngroup hn02

######### 2-4 完成了用户与资源的绑定 ##########

# 5. 修改share的属组权限,让hn01和hn02都有读share的权利(也就是可以cd进share),使二者成为当前软件的管理员
# 补充
# 1)管理员有两种:第一种是操作系统管理员,也就是root用户,第二种是某个或某些软件的管理员,也就是普通用户
# 2)修改权限有两种方式:第一种是字符型,比如将属主权限增加rwx,属组权限增加rw,其他人权限去掉rw,那么命令就可以写成chmod u+rwx g+rw o-rw; 第二种是数值型,也就是用二进制表示相应权限是否开启,并将其转成十进制作为指令来修改权限
# 3)如果修改当前用户的权限,在修改完权限之后重新进入该用户来刷新权限
# 4)文件夹权限一般是奇数,比如:755,文件权限一般是偶数,比如:664(相比文件夹权限少了x)
# 5)权限x,针对文件夹是cd,针对文件是执行;权限r表示读取文件夹或者文件的元信息

######### 5 完成了与权限的绑定 ##########

控制不同用户的权限

假设新安装了sql软件,增加了一个sql的管理员用户hnadmin,hnadmin有控制sql的sbin中服务的权限,而之前创建的普通用户hn01和hn02只有执行bin下客户端的权限

# 在opt下创建mysql
mkdir /opt/mysql

# 进入mysql创建bin和sbin
mkdir {bin, sbin}

# 增加一个管理员用户mysqladmin
useradd mysqladmin

# 递归地将mysql以及子目录的属主修改成新增的用户
chown -R mysqladmin:root mysql

# 增加一个虚拟的组mysqlgroup
groupadd mysqlgroup

# 将两个普通用户添加到新建的虚拟组里面
usermod -a -G mysqlgroup hn01
usermod -a -G mysqlgroup hn02

# 重新修改属主和属组信息
chown -R mysqladmin:mysqlgroup mysql

# 修改sbin目录下的权限,只有管理员有修改(w)的权限,其他人没有修改的权限
cd sbin
chmod 744 xxx.txt

# 进入bin目录下,使得普通人有执行的权利
chown mysqladmin:mysqlgroup mysqlcli.sh
chmod 754 myslqcli.sh

软件安装

软件安装一般分成三种类型,编译安装,包安装以及仓库安装。针对编译安装,虚拟机中会经常用到,比如想要嵌入个性化代码的时候会用到编译安装,但是编译过程(比如javac)往往不是很关心;针对包安装,由于不是所有的仓库都包含所有包,比如java分成open java(apache)以及oracle的java(需要license),后者的包就不再任意一个仓库里面,所以包安装(rpm)也比较重要;针对仓库的安装,仓库将依赖的jar包放在一起,比如maven仓库,所以仓库安装(yum)也有存在的必要性。下面就简单描述编译安装的一般流程

编译安装

  1. scp将压缩包上传到虚拟机
  2. tar xf解压压缩包,然后cd到源码的目录,使用make进行编译安装的前提需要有MakeFile文件,如果没有就读README来定位到安装部分的说明
  3. 查看帮助信息./configure --help | more,发现配置文件未来将安装到--prefix路径,如果没有路径会自动创建路径,执行./configure --prefix=/opt/hn/nginx
  4. 发现缺少c编译器,执行yum install gcc -y,再执行./configure --prefix=/opt/hn/nginx
  5. 发现缺少PCRE,执行yum search PCRE,发现有版本i686(32位)和i86(64位),yum会自动选择匹配操作系统的版本,执行yum install pcre-devel,输入yes,再执行./configure --prefix=/opt/hn/nginx
  6. 发现缺少openssl-devel,通过yum search openssl,执行yum install openss-devel,输入yes(yum会自动安装依赖)
  7. 出现makeFile后执行make,执行流程是首先定位到Makefile中的default,然后到built,然后到objs,最后到真正做事的obj下执行makeFile,这步是真正意义上的安装,即拷贝的过程
  8. 执行make install,执行流是make拿着install打开Makefile,然后定位到install章节,根据内容进入到objs/Makefile,最后找到install进行安装
  9. cd到/opt/hn/nginx,执行./nginx,因为nginx是webserver,因此可以访问192.168.79.31:80(不用加80的端口号也可以),页面是否成功来判断编译+安装+执行是否成功

补充

产生makeFile文件之后,用vi打开它可以看到

default: build
build: obj/makeFile

make是编译和安装的命令, 执行make开始进行编译的时候,如果make后面没有参数,那就默认执行makeFile文件中的default,然后调用built,进而执行obj下面的makeFile进行编译,编译用到的编译器是gcc,其中gcc就是将C语言开源的gnu开源的C语言编译器