第 1 章 Linux 文件与目录结构
Linux 系统中一切皆文件。
- /bin:存放最经常使用的命令
- /boot:启动 Linux 时使用的核心文件
- /etc:所有系统管理所需的配置文件和子目录
- /home:存放普通用户的用户主目录
- /root:系统管理员的用户主目录
- /sbin:存放系统管理员使用的系统管理程序
- /tmp:存放临时文件
- /usr:用户的应用程序和文件都放在这个目录下
- /opt:额外安装软件所在的目录(mysql、redis、zookeeper 等都放在这)
- /lib:库文件目录,包含了所有对系统有用的库文件
- /var:将经常被修改的日志文件放在这个目录
1.1 ./
、../
、~/
.
或./
代表当前目录..
或../
代表上一层目录~/
代表主目录
1.2 ls
ls 的语法是:
ls [options] /path
options 参数 | 说明 |
---|---|
ls -l / ll | 以长格式显示文件和目录信息,包括权限、所有者、大小、创建时间等 |
ls -a | 显示所有文件及目录 |
ls -d | 只列出目录 |
ls -t | 按照修改时间排序,最新的文件在最前面 |
ls -R | 递归显示目录中的所有文件和子目录 |
/path 路径可以使用通配符进行模式匹配:
ls *.txt # 列出所有扩展名为 .txt 的文件
ls file?.txt # 列出文件名为 file?.txt 的文件,其中 ? 表示任意一个字符
ls a*.txt # 列出以 a 开头、扩展名为 .txt 的文件
-
在使用 ll 命令时,第一列的字符表示文件或目录的类型和权限。其中第一个字符表示文件类型,例如:
-
表示普通文件- d 表示目录
- l 表示链接文件(蓝色)
-
第一列的其余 9 个字符表示文件或目录的访问权限,分别对应三个字符一组的 rwx 权限:
1.3 chmod
chmod 777 <file> # 修改文件权限为所有人可读可写可执行
chmod u+x <file> # 修改文件权限为用户可执行文件
参数 | 说明 |
---|---|
r | 可读权限,八进制为 4 |
w | 可写权限,八进制为 2 |
x | 可执行权限,八进制为 1 |
- | 没有对应权限,八进制为 0 |
u+x | 用户增加执行权限 |
g-w | 用户所属组移除写权限 |
a=r | 每个用户都可以读 |
1.4 chown
chown -R user[:group] <directory> # 改变该目录的所有者
chown -R user[:group] <file> # 改变文件的所有者
参数 | 说明 |
---|---|
user | 新的文件拥有者的使用者 |
group | 新的文件拥有者的使用者组 |
1.5 cd
cd <directory> # 切换目录
cd # 切换到根目录
cd - # 切换到上一个操作的目录
cd .. # 切换到当前目录的上一级目录
1.6 mkdir
mkdir -p <directory> # 创建目录
mkdir -p <directory>/<directory>/... # 创建多级目录
1.7 rm
rm -rf <directory> # 强制删除目录
rm -rf <file> # 强制删除文件
1.8 cp
cp [options] source dest # source 表示要复制的文件或目录的路径,dest表示复制后的文件或目录的路径
options 参数 | 说明 |
---|---|
cp -r | 递归复制整个文件夹 |
1.9 mv
mv <source_file> <dest_file> # 将源文件 source_file 重命名为 dest_file
mv <source_file> <dest_directory> # 将源文件 source_file 移动到目标目录 dest_directory 中
mv <source_directory> <dest_directory> # 如果 dest_directory 存在,将源目录移动到目标目录中
# 如果 dest_directory 不存在,重命名源目录
1.10 head / tail
head -n 2 <file> # 查看一个文件的前两行
tail -f -n 100 <file> # 查看文件最新追加的 100 条内容
第 2 章 用户管理类
2.1 useradd
useradd <user-name> # 添加一个用户
useradd -g <group-name> <user-name> # 添加用户到某个用户组
2.2 password
password <user-name> # 更改用户密码
2.3 id
id <user-name> # 查看该用户的 uid,gid,和所属组
2.4 su
su <user-name> # 从 root 用户切换到指定用户
2.5 设置普通用户具有 root 权限
sudo vim /etc/sudoers
# Allow root to run any commands anywhere
root ALL=(ALL) ALL
username ALL=(ALL) ALL
第 3 章 搜索查找类
3.1 find
find 直接查找硬盘,速度较慢,但是查询结果精确。
find / -name <file> # 根据名称查找所在目录下的文件
find <directory> -name "*.txt" # 查找 directory 目录下以 txt 结尾的文件
find <directory> -user <user-name> # 查找指定用户在 directory 目录下的所有文件
3.2 whereis
whereis 查询速度高于 find,因为它仅针对 /bin/sbin 下面的执行文件,以及 /use/share/man 下面的 man page 文件等进行处理。
whereis <file> 或 <directory>
3.3 locate
locate 利用已建立的数据库 /var/lib/mlocate 里面的数据,不用去硬盘读取,所以查询速度快。
updatedb # 创建或更新 locate 数据库
locate tmp # 查找包含 tmp 的所有目录或文件
3.4 脚本文件的查找 which
which <command> # 查找 PATH 目录下 command 命令的完整文件名
which 无法查找 bash 内置命令,因为它们不在 PATH 环境变量规范路径下。which ****可以查找的命令大多数在 /bin 目录下。
3.5 type
type <command> # 显示该命令是外部命令还是 bash 内置命令
3.6 过滤查找 grep 及管道操作符 |
grep -n <context> <file-name> # 查找出文件中的所有 context 内容,并显示行号
管道操作符|将前一个命令的输出作为后一个命令的输入:
ls | grep .cfg # 列出当前目录下以 .cfg 结尾的文件
第 4 章 磁盘管理类
4.1 du
du -h # 查看当前目录所有文件所占磁盘空间
du -sh # 仅查看当前目录所占磁盘空间
4.2 df
df -h # 列出文件系统整体磁盘使用量
输出结果信息:
- Filesystem:代表该文件系统是哪个硬盘分区
- Size:总磁盘容量
- Used:已使用磁盘容量
- Available:剩下可用磁盘容量
- Use%:磁盘使用率
- Mounted on:磁盘挂载点
4.3 lsblk
lsblk # 查看设备挂载情况
输出结果中,磁盘的 Name 如果是 dev/hdxx,则为 IDE 磁盘。如果是 dev/sdxx,则为 SCSI/SATA/USB 磁盘。如果是 nvme0n1,则为 NVMe 磁盘。
第 5 章 进程管理类
5.1 进程
在 Linux 系统中,程序被触发时,执行者的权限和属性、程序的代码与所需数据等都会被加载到内存中,操作系统给予这个内存中的单元一个 PID,即进程是一个正在运行的程序。
5.1.1 fork-and-exec
父进程调用子进程的流程称为 fork-and-exec,具体流程如下:
- 操作系统以 fork 方式复制一个与父进程相同的临时进程,这个进程与父进程唯一的差别就是 PID 不同以及多出一个 PPID(Parent PID)。
- 该临时进程以 exec 方式加载实际要执行的进程,最终生成子进程的进程代码
5.1.2 服务
常驻在内存中的进程称为服务,它在后台启动并一直运行。
5.2 网络端口号
netstat –nltp | grep <port> # 查看某端口号是否被占用
5.3 查看进程
ps -ef # 显示所有进程信息
ps -ef | grep <pid> # 显示进程号为 pid 的进程信息
ps -ef | grep <process-name> # 显示某进程的信息
执行命令显示结果如下:
- 第一列 UID,第二列 PID,第三列 PPID
- 第四列 C 指 CPU 占用率
- 第五列 STIME 指程序的启动时间
- 第六列 TTY 指进程登录终端,若无闲事与终端无关显示 ?,若为网络连接进入主机的进程显示 pts/0
- 第七列 TIME 指进程实际使用 CPU 的时间
- 第八列 CMD 指启动这个进程的命令
ps aux
执行命令显示结果如下:
- 第一列 USER 指进程所属用户
- 第二列 PID 指进程 ID
- 第三列 %CPU 指使用 CPU 百分比
- 第四列 % MEM 指占用物理内存百分比
- 第五列 VSZ 指占用虚拟内存量(KB)
- 第六列 RSS 指占用固定内存量(KB)
- 第七列 TTY 指该进程运行终端
- 第八列 STAT 指该进程当前状态
字符 | 说明 |
---|---|
R | Running 运行中 |
S | Sleeping 睡眠中 |
D | 不可唤醒的睡眠状态,通常该进程可能在等待 IO |
I | 闲置内核线程 |
T | 停止状态,在任务控制(后台暂停)下停止 |
t | 停止状态,在跟踪状态下由 debugger 停止 |
Z | 僵尸状态,进程已经终止但无法从内存删除 |
< | 高优先级 |
N | 低优先级 |
L | 将页面锁定在内存中 |
s | session leader,包含子进程的主进程 |
l | 多线程进程 |
+ | 位于前台的进程组 |
- 第九列 START 指进程触发启动的时间
- 第十列 TIME 指进程实际使用 CPU 的时间
- 第十一列 COMMAND 指启动这个进程的命令
5.3 删除进程
kill -9 <pid>
5.4 top
top # 查看所有进程信息
top -p <pid> # 仅查看指定 pid 的进程信息
命令显示的内容:
- 第一行:任务队列消息,包括系统当前时间,已运行时间,当前登录用户数量以及系统在 1 、5、15 分钟的平均任务负载
- 第二行:进程数量信息,包括运行进程、睡眠进程、停止进程和僵尸进程数量
- 第三行: CPU 信息,us 是用户空间占用 CPU 的百分比;sy 是内核空间占用 CPU 的百分比;id 是空闲 CPU 百分比;wa 是 IO 等待占用 CPU 的百分比
- 第四行:物理内存信息
- 第五行:交换分区信息
- 第七行以下:各进程(任务)的状态监控
PR — 进程优先级,越小越早执行
NI — nice 值,越小越要执行
VIRT — 进程使用的虚拟内存大小,单位 kb
RES — 进程使用的物理内存大小,单位 kb
SHR — 共享内存大小,单位 kb
S —进程状态,R 是运行状态,S 是睡眠状态
%CPU — CPU 时间占用百分比
%MEM — 进程使用的物理内存百分比
TIME+ — 进程使用的 CPU 时间总计,单位 1/100 秒
COMMAND — 进程名称
5.5 pstree
pstree -p # 查看进程之间相关性
所有进程都是依附在 systemd 进程下面,该进程 PID=1,因为它是内核主动调用的第一个进程。
第 6 章 系统服务类
服务是常驻在内存中的进程,而 daemon 则是完成这个服务的进程。在 Linux 中使用 top 或者 ps 查看进程时,可以看到很多服务名称后面加个 d,这个 d 就代表 daemon。
查看所有服务:
cd /usr/lib/systemd/system
ls
服务类型的扩展名有以下几种:
扩展名 | 主要服务 |
---|---|
.service | 一般服务类型,主要是系统服务,包括本地服务和网络服务 |
.socket | 内部程序数据交换的 socket 服务 |
6.1 通过 systemctl 管理单一服务的启动和查看状态
systemctl start <service> # 立刻启动服务
systemctl stop <service> # 立刻关闭服务
systemctl status <service> # 查看服务状态
systemctl restart <service> # 立刻重启服务
systemctl reload <service> # 不关闭服务情况下,重新加载配置文件
systemctl enable <service> # 设置服务开机自启动
systemctl disable <service> # 禁止服务开机自启动
systemctl is-active <service> # 查看服务有没有正在运行中
systemctl is-enable <service> # 查看服务是否开机自启动
6.2 通过 systemctl 查看系统上的所有服务
systemctl list-units # 显示目前启动的服务
systemctl list-unit-files # 显示所有系统服务
systemctl list-units --type=service --all # 显示所有 service 类别的服务
6.3 通过 systemctl 分析服务之间的依赖性
systemctl get-default # 当前 target 环境,结果为 graphical.target 就是图形界面,multi-user.target 就是纯命令行
systemctl list-dependencies graphical.target
第 7 章 Shell 编程
管理整个计算机硬件的是操作系统的内核,一般用户只能通过 shell 来和内核沟通。
7.1 脚本的常用执行方式
在当前 shell 下可以使用 bash 命令进入到子进程中,在一般状态下,当前 shell 的自定义变量无法在子进程中使用,而环境变量可以。
这是因为启动一个 shell,OS 会分配一内存区域给 shell 使用,若在该 shell 中使用 export,会将自定义变量写到该内存区域中。
当在该 shell 中启动子进程,子进程可以将父进程的环境变量所在内存区域导入自己的环境变量内存区域中
第一种:脚本路径前加上 bash 或者./
,脚本首先必须具有执行权限。该执行方式是在当前 shell 中打开一个子进程来执行脚本内容,脚本结束后子进程关闭,回到当前 shell 中:
chmod +x xxx.sh
./xxx.sh
第二种:在脚本的路径前加上 source 或者.
。该执行方式使脚本内容在当前 shell 里执行:
source xxx.sh
. xxx.sh
7.2 变量的使用与设置
7.2.1 变量的使用与 echo
${变量} 可以使用变量,echo ${变量} 可以打印变量值:
${变量} # 使用变量
echo ${变量} # 打印变量值
如果变量未被设置则输出为空。
7.2.2 变量的设置
变量的设置规则如下:
- 变量名称可以由字母、数字和下划线组成,但是不能以数字开头,环境变量名建议大写
- 变量与变量值用等号连接,等号两侧不能有空格
- 变量默认类型都是字符串类型
- 双引号内的特殊字符保持原本的含义
var="$LANG"
# echo ${var} 输出 zh_CN.UTF-8
-
单引号内的特殊字符为纯文本
- 如果要让该变量在其他子程序中执行,加上 export 使变量变成环境变量
- 如果有特殊字符(空格、
、`'`等)需要在前面加上转义字符
- 如果在一串命令执行时,还需要引用其他额外命令提供信息时,使用 $(命令)
var='$PATH'
# echo ${var} 输出 $PATH
var='my\ name'
# echo ${var} 输出 my name
var='$(uname -r)'
# echo ${var} 输出你的虚拟机内核版本号
7.2.2.1 扩增变量内容
PATH=${PATH}:/bin
# 在原来 PATH 变量值后面添加 :/bin
7.2.2.2 定义数组类型或整数类型变量值
使用 declare 命令:
declare -a <变量名=变量值> # 将变量值定义为数组类型
declare -i <变量名=变量值> # 将变量值定义为整数类型
declare -x <变量名=变量值> # 将变量定义为环境变量
sum=100+50
# echo ${sum} 得到字符串 100+50
declare -i sum=100+50
# echo ${sum} 得到 150
7.2.2.3 变量的键盘读取
read -p <变量名> # 会出现一个空白行等待键盘输入变量值
7.2.2.4 取消设置的变量
unset <变量名>
7.3 变量的删除和替换
变量设置方式 | 说明 |
---|---|
${变量#关键词} | 若变量内容从头开始的数据符合关键词,将符合的最短数据删除 |
${变量##关键词} | 若变量内容从头开始的数据符合关键词,将符合的最长数据删除 |
${变量%关键词} | 若变量内容从尾向前的数据符合关键词,将符合的最短数据删除 |
${变量%%关键词} | 若变量内容从尾向前的数据符合关键词,将符合的最长数据删除 |
${变量/旧字符串/新字符串} | 若变量内容符合旧字符串,则从头到尾第一个旧字符串被新字符串替换 |
${变量//旧字符串/新字符串} | 若变量内容符合旧字符串,则全部旧字符串被新字符串替换 |
${变量-新变量值} | 若变量已经存在或为空字符串,保持不变;若变量不存在,设置为新变量值 |
${变量:-新变量值} | 若变量已经存在,保持不变;若变量不存在或为空字符串,设置为新变量值 |
7.4 环境变量
在当前 shell 中使用 env 或 export 命令可以查看所有的环境变量:
环境变量 | 说明 |
---|---|
HOME | 用户的根目录 |
SHELL | /bin/bash |
HISTSIZE | history 显示命令的条数,默认 1000 |
HOSTNAME | 当前主机名 |
PATH | 执行文件查找路径 |
PWD | 当前工作目录 |
USER | 当前用户 |
7.5 系统变量
以下是一些特殊变量:
$0
,当前脚本名称$n
,n 为数字,当前脚本的第 n 个参数$#
,获取脚本输入参数总个数$*
,获取脚本所有输入参数,把所有的参数看成一个整体$@
,获取脚本所有输入参数,把每个参数区分开$?
,表示最后一次执行的命令的返回状态。如果这个变量的值为 0,证明上一个命令正确执行;如果这个变量的值非 0,则证明上一个命令执行不正确$$
,程序本身的 pid
6.2.4 字符串变量
字符串变量建议使用双引号括起来,双引号的优点:
- 双引号里可以有变量
- 双引号里可以出现转义字符
获取字符串长度:
string="abcd"
echo ${#string}
提取子字符串:
string="alibaba"
# 输出索引 1-5 的字符串(Java 输出索引 1-4)
echo ${string:1:5}
6.2.5 数组变量
只支持一维数组,没有限定数组大小。定义数组:
array_name=(val1 val2 ...)
读取数组:
${数组名[下标]}
# 获取所有元素
${数组名[@]}
# 获取数组长度
${#数组名[@]}
7.6 变量数值运算
以下两种表达时皆可,推荐使用第一种:
val=$(( 运算内容 ))
val=$[ 运算内容 ]
注意运算内容和括号空格隔开。
7.7 变量条件判断和 test
test 命令可以判断后面跟的表达时的真假,结合其他一些条件判断运算符:
7.7.1 判断文件类型
命令 | 说明 |
---|---|
test -e 或者 [ -e ] | 判断文件 file 是否存在 |
test -f 或者 [ -f ] | 判断 file 是否存在且为文件 |
test -d 或者 [ -d ] | 判断 file 是否存在且为目录 |
7.7.2 判断文件权限
命令 | 说明 |
---|---|
test -r 或者 [ -r ] | 判断 file 是否存在且有可读权限 |
test -w 或者 [ -w ] | 判断 file 是否存在有可写权限 |
test -x 或者 [ -x ] | 判断 file 是否存在且有可执行权限 |
7.7.3 比较判断和逻辑判断
命令 | 说明 |
---|---|
test p -eq / -ne q 或者 [ p -eq / -ne q ] | 判断 p 等于 / 不等于 q |
test p -lt / -gt q 或者 [ p -lt / -gt q ] | 判断 p 小于 / 大于 q |
test p -le / -ge q 或者 [ p -le / -ge q ] | 判断 p 小于等于 / 大于等于 q |
test <条件1> -a <条件2> 或者 [ <条件1> -a <条件2> ] | 条件 1 和条件 2 必须同时成立 |
test <条件1> -o <条件2> 或者 [ <条件1> -o <条件2> ] | 条件 1 和条件 2 只需有一个成立 |
test ! <条件> 或者 [ ! <条件> ] | 判断条件不成立 |
7.7.4 字符串的判断
命令 | 说明 |
---|---|
test -z 或者 [ -z ] | 判断 string 是否为空,空为 true |
test -n 或者 [ -n ] | 判断 string 是否非空,非空为 true,-n 能省略 |
test str1 == str2 或者 [ str1 == str2 ] | 判断 str1 是否等于 str2 |
7.8 流程控制(⭐)
7.8.1 if
单分支:
if [ 条件判断式 ]
then
程序
fi
多分支:
if [ 条件判断式 ]
then
程序
elif [ 条件判断式 ]
then
程序
else
程序
fi
注意事项: [ 条件判断式 ] 的中括号和条件判断式之间必须有空格;if 后要有空格
7.8.2 case 语句
case $变量名 in
"值 1")
如果变量的值等于值 1,则执行程序 1
;;
"值 2")
如果变量的值等于值 2,则执行程序 2
;;
省略其他分支 ...
*)
如果变量的值都不是以上的值,则执行此程序
;;
esac
;; 表示命令序列结束,相当于 java 中的 break。*)表示默认模式,相当于 java 中的 default。
7.8.3 for 循环
for (( 初始值;循环控制条件;变量变化 ))
do
程序
done
for 变量 in 值1 值2 值3…
do
程序
done
7.8.4 while 循环
while [ 条件判断式 ]
do
程序
done
7.9 shell 脚本的跟踪与调试
sh -n xxx.sh # 不执行脚本,检查脚本的语法,没有问题则不显示任何信息
sh -x xxx.sh # 列出脚本的执行过程
升级 ubuntu 内核
ubuntu20.04 升级到 ubuntu22.04:
sudo apt update && sudo apt upgrade -y
reboot
sudo do-release-upgrade -d
lsb_release -a
第 8 章 Ubuntu 初始化配置
8.1 Vmware 安装 Ubuntu 时界面显示不全
该问题的产生是因为 Ubuntu 分辨率的问题,所以可以通过终端修改分辨率来解决。使用 Ctrl+Alt+t 打开终端。输入:
xrandr
查看支持的分辨率。选择其中最大分辨率。我的是 3840x2400 59.97。输入命令:
xrandr -s 3840x2400_59.97
8.2 更新软件源为清华源
首先备份源列表文件:
sudo cp /etc/apt/sources.list /etc/apt/sources.list.bak
然后打开源列表文件:
sudo vi /etc/apt/sources.list
输入以下内容替换原来所有内容:
deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ focal main restricted universe multiverse
deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ focal-updates main restricted universe multiverse
deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ focal-backports main restricted universe multiverse
deb http://security.ubuntu.com/ubuntu/ focal-security main restricted universe multiverse
保存退出后更新列表:
sudo apt-get update
安装 vim:
sudo apt-get install vim -y
8.3 远程访问本机
首先安装以下两个工具:
sudo apt install openssh-server -y
sudo apt install net-tools -y
启动 ssh 服务:
sudo systemctl start ssh
sudo systemctl enable ssh
sudo ufw disable
查看虚拟机 ip:
ifconfig
第 9 章 Ubuntu 安装软件
9.1 Docker
官方提供了脚本安装命令:
sudo apt install curl -y
curl -fsSL get.docker.com -o get-docker.sh
sudo sh get-docker.sh --mirror Aliyun
sudo systemctl enable docker
sudo systemctl start docker
docker --version
Docker 命令免去 sudo 权限方法:
sudo groupadd docker
sudo gpasswd -a ${USER} docker
sudo chmod a+rw /var/run/docker.sock
sudo systemctl restart docker
9.2 Java8
sudo apt install openjdk-8-jdk-headless
java -version
9.5 GitLab
虚拟机要求 4G 以上内存,最好 6G。
下载安装官方文档:https://gitlab.cn/install/?version=ce
安装依赖项:
sudo apt-get update
sudo apt-get install -y curl openssh-server ca-certificates tzdata perl
配置镜像:
curl -fsSL https://packages.gitlab.cn/repository/raw/scripts/setup.sh | /bin/bash
执行如下命令开始安装:
sudo EXTERNAL_URL="https://gitlab.example.com" apt-get install gitlab-jh
安装成功后,启动 Gitlab 所有组件:
sudo gitlab-ctl start
在浏览器中使用 ip 登录:
首次登录用户名是 root,密码在 /etc/gitlab/initial_root_password 文件里(该密码只有 1 天有效时间):
sudo cat /etc/gitlab/initial_root_password
登录后修改密码,还可以设置中文语言。
第 10 章 常见问题解决方法
10.1 ifconfig 查看没有 ens33 网卡
输入 ifconfig -a 查看,如果可以找到 ens33 网卡,说明是 ens33 网卡状态异常。首先停止网络服务:
service network-manager stop
删除设备网卡状态管理文件:
sudo rm -rf /var/lib/NetworkManager/NetworkManager.state
重新启动网络服务:
service network-manager start
ifconfig