Linux系统及应用学习笔记
系统管理
1 帮助命令
1.1 内建命令
1
|
它是shell程序的一部分,写在Bash源码之中。
|
1.2 外部命令
-
包括:
-
通常放在:
/bin
/sbin
/usr/bin
/usr/sbin
1.3 如何区分内建命令与外部命令
1
2
3
4
5
6
7
8
|
type exit
# exit is a shell builtin
type vim
# vim is /usr/bin/vim
type ls
# ls is an alias for ls --color=tty
|
1.4 帮助命令
1.4.1 man
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
# pageup pagedown or up down
# q to quit
man ls
# LS(1..9)
# 1 Standard commands (标准命令)
# 2 System calls (系统调用)
# 3 Library functions (库函数)
# 4 Special devices (设备说明)
# 5 File formats (文件格式)
# 6 Games and toys (游戏和娱乐)
# 7 Miscellaneous (杂项)
# 8 Administrative Commands (管理员命令)
# 9 其他(Linux 特定的), 用来存放内核例行程序的文档。
|
1.4.2 info
2 目录结构
2.1 目录路径
- cd
cd ~
# 切换到用户主目录
cd ~
# 切换到用户主目录
cd -
# 切换到上一次的目录
cd ..
# 切换到上一级目录
cd ../..
# 切换到上上级目录
cd /
# 切换到根目录
cd /home/ubuntu/xxx
# 切换到指定目录
pwd
# 显示当前目录
3 文件的基本操作
3.1 新建
touch
touch xxx
# 创建文件xxx;如果文件已存在,则会更新文件的时间戳
mkdir
mkdir xxx
# 创建目录xxx
mkdir -p father/son
# 创建父目录father,并创建子目录son
mkdir xxx
# 创建目录xxx, 如果目录已存在,则不创建;如果文件已存在,则报错
3.2 复制
cp
cp xxx yyy
# 复制文件xxx到yyy
cp -r xxx yyy
# 递归复制文件夹(子文件夹及子文件)xxx到yyy
3.3 移动
mv
- 移动
mv xxx yyy
# 移动文件xxx到yyy
mv -r xxx yyy
# 递归移动文件夹(子文件夹及子文件)xxx到yyy
- 重命名
mv file1 mfile1
# 将文件file1重命名为mfile1
- 批量重命名
rename
的第二个参数为通配符,第一个参数为正则表达式,类似sed
1
2
3
4
5
6
7
8
|
# 创建5个文件, 名为file1.txt, file2.txt, file3.txt, file4.txt,file5.txt
touch file{1..5}.txt
# 批量将后缀为.txt的文件重命名为.txt.bak
rename 's/\.txt$/.txt.bak/' *.txt
# 批量将这5个文件的文件名改成大写
rename 'y/a-z/A-Z/' *.txt.bak
|
3.4 删除
rm
rm xxx
# 删除文件xxx
rm -r xxx
# 递归删除文件夹(子文件夹及子文件)xxx
rm -f xxx
# 删除文件xxx,如果文件存在,则会忽略提示;如果文件不存在,则不报错
rm -rf xxx
# 强制删除文件夹(子文件夹及子文件)xxx
3.5 查看文件
-
cat
-n
# 查看文件xxx的内容,并显示行号
-n ln
# 在行号字段最左端显示
-n rn
# 在行号字段最右边显示,且不加 0
-n rz
# 在行号字段最右边显示,且加 0
-b
# 指定添加行号的方式,主要有两种
-b a
# 无论是否为空行,均列出行号(cat -n
就是这种方式)
-b t
# 只列出非空行的编号并列出(默认为这种方式)
-c
# 查看文件xxx的内容,并显示字符数
-e
# 查看文件xxx的内容,并显示行号,以及每行的长度
-l
# 查看文件xxx的内容,并显示行号,以及每行的长度
-w
# 行号字段占用的位数(默认为 6 位)
-
more
more xxx
# 打开后默认只显示一屏内容,终端底部显示当前阅读的进度。可以使用Enter
键向下滚动一行,使用Space
键向下滚动一屏,按下h
显示帮助,q
退出。
-
tail
tail /etc/passwd
# 查看文件/etc/passwd的最后10行
tail -n 1 /etc/passwd
# 查看文件/etc/passwd的最后一行
tail -f /etc/passwd
# 查看文件/etc/passwd的最后十行,并且每隔一秒更新一次
-
file
file /bin/ls
# 查看文件/bin/ls的文件类型
-
ls
ls -a
# 查看所有文件,包括隐藏文件
ls -A
# 查看所有文件,包括隐藏文件,不包括.
和..
ls -l
# 以列表形式查看文件的详细信息
ls -h
# 以人类可读的方式显示文件大小
ls -v
# 按照文件名中的数字以自然顺序排序
ls -t
# 按照文件的修改时间排序, 默认新的在前面
ls -r
# 逆序排列结果
ls -R
# 递归查看文件夹
ls -S
# 按照文件大小排序
1
|
与 Windows 不同的是,如果你新建了一个 shiyanlou.txt 文件,Windows 会自动把它识别为文本文件,而 file 命令会识别为一个空文件。这个前面我提到过,在 Linux 中文件的类型不是根据文件后缀来判断的。当你在文件里输入内容后才会显示文件类型。
|
cut
-b
# 按字节分割
-c
# 按字符分割
-d
# 按间隔符分割
-f
# 按域分割
1
2
|
# 在当前目录下, 以/etc/passwd第三行中:为分隔符的第一个字段创建一个新文件
cat /etc/passed | head -n 3 | tail -n 1 | cut -d : -f 1 | xargs touch
|
3.6 搜索文件
1
|
whereis 只能搜索二进制文件(-b),man 帮助文件(-m)和源代码文件(-s)。如果想要获得更全面的搜索结果可以使用 locate 命令。
|
locate
loacte /etc/sh
# 查找/etc/bin目录下所有以sh开头的文件
loacte /usr/share/\*.jpg
# 查找/usr/share目录下所有的.jpg文件;\*
表示任意字符,而不是任意数量的字符; \
表示转义字符
locate -c /etc/sh
# 查找/etc/bin目录下所有以sh开头的文件的数量
loacte -i /etc/sh
# 查找/etc/bin目录下所有以sh开头的文件并忽略大小写
1
2
|
sudo apt-get install locate
sudo updatedb
|
1
|
which 本身是 Shell 内建的一个命令,我们通常使用 which 来确定是否安装了某个指定的程序,因为它只从 PATH 环境变量指定的路径中去搜索命令并且返回第一个搜索到的结果。也就是说,我们可以看到某个系统命令是否存在以及执行的到底是哪一个地方的命令。
|
find
find [path] [option] [action]
sudo find /etc/ -name interface
# 查找名为interface的目录或文件
-mtime n
# 在 n 天之前的“一天之内”修改过的文件
-mtime +n
# 在 n 天之前(不包含 n 天本身)被修改过的文件
-mtime -n
# 列出在 n 天之内(包含 n 天本身)被修改过的文件
-mtime file
# file 为一个已存在的文件,列出比 file 还要新的文件名
-type
# 指定查找类型
-empty
# 查找对象为空的
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
# 列出home目录下,最近修改时间在一天之内的文件
find ~ -mtime 0
# 列出home目录下比/etc目录新的文件
find ~ -newer /etc
# 找出home目录下大小超过1块(512字节)的文件
find ~ -size +1
# 找出home目录下大小超过1块(512字节)的文件,并将其保存到/tmp目录下
find ~ -size +1 -exec cp {} /tmp \;
# 统计home目录下大小超过1块(512字节)的文件数量
find ~ -size +1 | wc -l
# 找出/etc/目录下所有以 .list 结尾的文件
sudo find /etc/ -name *.list
or
sudo find /etc -name "*.list"
|
1
2
3
4
5
|
# 删除当前目录下的空目录
find . -type d -empty -exec rm -rf {} \;
# 为当前目录下的所有符号链接文件添加.ln的后缀名
find . -type l -exec mv {} {}.ln \;
|
3.7 文件打包
/解包
/压缩
/解压缩
1
2
3
4
5
6
7
8
9
10
11
|
*.zip zip 程序打包压缩的文件
*.rar rar 程序压缩的文件
*.7z 7zip 程序压缩的文件
*.tar tar 程序打包,未压缩的文件
*.gz gzip 程序(GNU zip)压缩的文件
*.xz xz 程序压缩的文件
*.bz2 bzip2 程序压缩的文件
*.tar.gz tar 打包,gzip 程序压缩的文件
*.tar.xz tar 打包,xz 程序压缩的文件
*tar.bz2 tar 打包,bzip2 程序压缩的文件
*.tar.7z tar 打包,7z 程序压缩的文件
|
-
zip
-r
# 递归打包
-q
# 打包时不显示提示信息
-o
# 打包输出文件,后面紧跟文件名;若不指定,则默认为当前目录的文件名
-[1-9]
# 压缩级别,默认为6;压缩级别越高,压缩后的文件越小
-x
# 排除文件
-l
# 将LF替换为CRLF
-
unzip
-q
# 以静默方式解包,不显示解包过程
-d
# 解包后文件存放的目录
-l
# 仅显示zip文件的内部信息
-O
# 指定编码类型
1
|
使用 unzip 解压文件时我们同样应该注意兼容问题,不过这里我们关心的不再是上面的问题,而是中文编码的问题,通常 Windows 系统上面创建的压缩文件,如果有有包含中文的文档或以中文作为文件名的文件时默认会采用 GBK 或其它编码,而 Linux 上面默认使用的是 UTF-8 编码,如果不加任何处理,直接解压的话可能会出现中文乱码的问题(有时候它会自动帮你处理),为了解决这个问题,我们可以在解压时指定编码类型。
|
1
2
|
# 使用 -O(英文字母,大写 O)参数指定编码类型
unzip -O UTF-8 -d /tmp /tmp/test.zip
|
du
# 显示文件大小
-h
# 以人类可读的方式显示
-d
# 设置递归深度,从0开始
1
|
关于 zip 命令,因为 Windows 系统与 Linux/Unix 在文本文件格式上的一些兼容问题,比如换行符(为不可见字符),在 Windows 为 CR+LF(Carriage-Return+Line-Feed:回车加换行),而在 Linux/Unix 上为 LF(换行),所以如果在不加处理的情况下,在 Linux 上编辑的文本,在 Windows 系统上打开可能看起来是没有换行的。如果要让在 Linux 创建的 zip 压缩文件在 Windows 上解压后没有任何问题,那么还需要对命令做一些修改.
|
1
2
|
# 将整个ubuntu文件夹打包成ubuntu.zip, 且将LF替换为CRLF
zip -r -l -o test.zip /home/ubuntu
|
tar
-c
# 创建一个tar包
-f
# 指定tar包的文件名,后面紧跟文件名
-P
# 保留绝对路径符
-v
# 以可视的方式输出打包的文件
-x
# 解包
-C
# 指定解包的目标文件夹,目标文件夹必须存在
-t
# 只查看,不解包
-p
# 保留文件属性
-h
# 备份链接指向的源文件而不是链接本身
-z
# 使用gzip压缩
--delete
# 删除压缩包中的文件
-xzf
# 解压.tar.gz
1
2
3
4
5
6
7
8
9
10
11
12
|
# 解压并解包test.tar.gz中的.txt文件
tar -tf test.tar.gz | grep .txt | xargs tar -xzvf test.tar.gz test{} \;
# 不解包test.tar.gz, 删除其中的blogs目录及其子文件和子文件夹
tar -vf test.tar.gz --delete blogs
# 打包多个文件, 将/etc/passwd和/etc/shadow文件打包到test.tar.gz中
tar -cf test.tar.gz /etc/passwd /etc/shadow
# 在位于当前目录下的Project目录中查找过去24小时产生的,大小大于5k,后缀名为.bak的文件,打包且不压缩, 放在
./Project目录下,并命名为bak.tar
find . -mtime 0 -size +5k -name *.bak | xargs tar -cvf bak.tar {} \;mv bak.tar ./Project
|
gzip
-d
# 解压.gz压缩包(不会解包, 文件名会退化为*.tar)
3.8 创建链接
ln target link_name
# 默认硬链接
1
2
3
4
5
|
# 在当前目录下为/etc/passwd创建一个名为passwd_hl的硬链接
sudo ln /etc/passwd passwd_hl
# 在当前目录下为/etc/passwd创建一个名为passwd_sl的符号链接
sudo ln -s /etc/passwd passwd_sl
|
4 数据流重定向
1
2
3
|
0 /dev/stdin # 标准输入
1 /dev/stdout # 标准输出
2 /dev/stderr # 标准错误
|
4.1 简单重定向
1
2
3
4
5
6
7
8
9
10
11
12
13
|
# 将 cat 的连续输出(heredoc 方式)重定向到一个文件
$ mkdir Documents
$ cat > Documents/test.c <<EOF
#include <stdio.h>
int main()
{
printf("hello world\n");
return 0;
}
EOF
|
4.2 标准错误重定向
1
2
3
4
5
|
# 将标准错误(2)重定向到标准输出(1), 再将标准输出(1)重定向到一个文件
cat test.c > afile 2>&1
# 利用bash内置的&, 将标准错误和标准输出同时重定向
cat test.c &> afile
|
使用tee
命令同时重定向到多个文件
1
2
|
# 利用tee命令, 在重定向文件的同时, 将重定向的内容输出到标准输出
cat test.c | tee afile bfile cfile
|
当前进程重定向
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
# 开启shell子进程
zsh
# 使用exec替换当前进程的重定向, 将标准输出重定向到一个文件
exec 1> redirectFile
# 测试命令
ls
# 退出子进程
exit
# 查看重定向的文件内容
cat redirectFile
|
5 命令的组合
5.1 有选择地执行命令
1
2
3
4
5
6
7
|
# &&符号前的命令执行状态的结果为0(成功), 则执行&&符号后的命令
which cowsay>/dev/null && cowsay -f head-in ohch~
# 通过执行$?来检查上一条命令的执行状态
$?
# 当cowsay已安装时,执行$?返回结果为0,即which cowsay执行成功,那么当which cowsay执行完后,若后面为&&连接的,则执行后半段命令;若后面为||连接的,则不执行后半段命令;反之,执行$?返回结果为1,即which cowsay执行失败,那么当which cowsay执行完后,若后面为&&连接的,则不执行后半段命令;若后面为||连接的,则执行后半段命令。
|
5.2 管道
1
|
ls -al /etc | grep 'pass'
|
5.3 cut
1
2
|
# 打印/etc/passwd文件中以:为分隔符的第 1 个字段和第 6 个字段分别表示用户名和其家目录
cut /etc/passwd -d : -f1,6
|
1
2
3
4
5
6
7
8
9
10
11
|
# 前5个字符
cut /etc/passwd -c -5
# 后5个字符
cut /etc/passwd -c 5-
# 第5个字符
cut /etc/passwd -c 5
# 第2个字符到第5个字符
cut /etc/passwd -c 2-5
|
5.4 grep
grep
-r
# 递归搜索
n
# 显示行号
I
# 忽略二进制文件
1
2
|
# 查看环境变量中以“ntu”结尾的字符串
export | grep ".*ntu$"
|
1
2
3
4
5
|
# 提取data文件中所有以数字开头的行到文件num
grep -n "^[0-9].*" data >> num
# 提取data文件中邮箱格式正确的行到文件email
grep -E "^[a-zA-Z0-9_]*@[a-zA-Z0-9_-]*\.[a-zA-Z]*$" data >> email
|
5.5 wc
wc
-l
# 行数
-w
# 单词数
-c
# 字节数
-m
# 字符数
-L
# 最长行字节数
1
|
对于西文字符来说,一个字符就是一个字节,但对于中文字符一个汉字是大于 2 个字节的,具体数目是由字符编码决定的。
|
1
2
|
# 统计/etc目录下的目录数
ls -dl /etc/*/ | wc -l
|
5.6 sort
sort
# 默认字典序排序
-t
# 指定分隔符
-k
# 指定排序字段
-n
# 按数字排序
1
2
|
# 将/etc/passwd文件中以:为分隔符的第3个字段排序,按数字排序
cat /etc/passwd | sort -t: -k3 -n
|
5.7 uniq
1
2
3
4
|
# 输出历史命令(过滤重复部分)
history | cut -c 8- | cut -d ' ' -f1 | sort | uniq
# 或
history | cut -c 8- | cut -d ' ' -f1 | sort -u
|
1
|
uniq命令只能去连续重复的行,不是全文去重,所以得先排序。
|
1
2
3
4
|
# 输出历史命令(重复行)
history | cut -c 8- | cut -d ' ' -f1 | sort | uniq -dc
# 或
history | cut -c 8- | cut -d ' ' -f1 | sort | uniq -D
|
6 Linux进程管理
6.1 top
工具
1
|
top 工具是常用的一个查看工具,能实时的查看我们系统的一些关键信息的变化
|
top
q
# 退出程序
I
# 切换显示平均负载和启动时间的信息
P
# 根据 CPU 使用百分比大小进行排序
M
# 根据驻留内存大小进行排序
i
# 忽略闲置和僵死的进程,这是一个开关式命令
k
# 终止一个进程,系统提示输入 PID 及发送的信号值。一般终止进程用 15 信号,不能正常结束则使用 9 信号。安全模式下该命令被屏蔽。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
|
# 输出如下
top - 19:26:52 up 2 days, 13:08, 1 user, load average: 0.05, 0.11, 0.06
Tasks: 273 total, 1 running, 272 sleeping, 0 stopped, 0 zombie
%Cpu(s): 0.2 us, 0.2 sy, 0.0 ni, 99.5 id, 0.0 wa, 0.1 hi, 0.1 si, 0.0 st
MiB Mem : 6855.3 total, 4694.1 free, 745.3 used, 1415.9 buff/cache
MiB Swap: 3427.6 total, 3427.6 free, 0.0 used. 5830.0 avail Mem
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
56963 zx 20 0 11700 3436 2712 R 1.3 0.0 0:00.45 top
334 systemd+ 20 0 23880 12008 7944 S 0.3 0.2 0:04.18 systemd-resolve
439 root 20 0 341204 20392 16380 S 0.3 0.3 2:35.10 NetworkManager
1745 nobody 20 0 715304 19956 8048 S 0.3 0.3 4:45.81 frpc
56242 root 20 0 0 0 0 I 0.3 0.0 0:00.41 kworker/u12:2-flush-259:0
1 root 20 0 168664 10808 6924 S 0.0 0.2 1:19.89 systemd
2 root 20 0 0 0 0 S 0.0 0.0 0:00.17 kthreadd
3 root 0 -20 0 0 0 I 0.0 0.0 0:00.00 rcu_gp
4 root 0 -20 0 0 0 I 0.0 0.0 0:00.00 rcu_par_gp
6 root 0 -20 0 0 0 I 0.0 0.0 0:00.00 kworker/0:0H-events_highpri
8 root 0 -20 0 0 0 I 0.0 0.0 0:00.00 mm_percpu_wq
9 root 20 0 0 0 0 S 0.0 0.0 0:00.00 rcu_tasks_kthre
10 root 20 0 0 0 0 S 0.0 0.0 0:00.00 rcu_tasks_rude_
11 root 20 0 0 0 0 S 0.0 0.0 0:00.00 rcu_tasks_trace
12 root 20 0 0 0 0 S 0.0 0.0 0:01.06 ksoftirqd/0
13 root 20 0 0 0 0 I 0.0 0.0 0:12.59 rcu_preempt
14 root rt 0 0 0 0 S 0.0 0.0 0:00.64 migration/0
16 root 20 0 0 0 0 S 0.0 0.0 0:00.00 cpuhp/0
17 root 20 0 0 0 0 S 0.0 0.0 0:00.00 cpuhp/1
18 root rt 0 0 0 0 S 0.0 0.0 0:00.60 migration/1
19 root 20 0 0 0 0 S 0.0 0.0 0:00.11 ksoftirqd/1
21 root 0 -20 0 0 0 I 0.0 0.0 0:00.17 kworker/1:0H-kblockd
22 root 20 0 0 0 0 S 0.0 0.0 0:00.00 cpuhp/2
23 root rt 0 0 0 0 S 0.0 0.0 0:00.10 migration/2
24 root 20 0 0 0 0 S 0.0 0.0 0:00.15 ksoftirqd/2
26 root 0 -20 0 0 0 I 0.0 0.0 0:00.00 kworker/2:0H-events_highpri
27 root 20 0 0 0 0 S 0.0 0.0 0:00.00 cpuhp/3
28 root rt 0 0 0 0 S 0.0 0.0 0:00.59 migration/3
29 root 20 0 0 0 0 S 0.0 0.0 0:00.12 ksoftirqd/3
31 root 0 -20 0 0 0 I 0.0 0.0 0:00.00 kworker/3:0H-events_highpri
32 root 20 0 0 0 0 S 0.0 0.0 0:00.00 cpuhp/4
33 root rt 0 0 0 0 S 0.0 0.0 0:00.56 migration/4
34 root 20 0 0 0 0 S 0.0 0.0 0:00.09 ksoftirqd/4
37 root 20 0 0 0 0 S 0.0 0.0 0:00.00 cpuhp/5
38 root rt 0 0 0 0 S 0.0 0.0 0:00.53 migration/5
39 root 20 0 0 0 0 S 0.0 0.0 0:00.09 ksoftirqd/5
41 root 0 -20 0 0 0 I 0.0 0.0 0:00.00 kworker/5:0H-kblockd
|
1
2
3
4
5
|
# top 表示当前程序的名称
# 11:05:18 表示当前的系统的时间
# up 8 days,17:12 表示该机器已经启动了多长时间
# 1 user 表示当前系统中只有一个用户
# load average: 0.29,0.20,0.25 分别对应 1、5、15 分钟内 cpu 的平均负载
|
1
2
3
4
5
6
7
8
9
10
|
load average 在 wikipedia 中的解释是 the system load is a measure of the amount of work that a computer system is doing 也就是对当前 CPU 工作量的度量,具体来说也就是指运行队列的平均长度,也就是等待 CPU 的平均进程数相关的一个计算值。
我们该如何看待这个 load average 数据呢?
假设我们的系统是单 CPU、单内核的,把它比喻成是一条单向的桥,把 CPU 任务比作汽车。
load = 0 的时候意味着这个桥上并没有车,cpu 没有任何任务;
load < 1 的时候意味着桥上的车并不多,一切都还是很流畅的,cpu 的任务并不多,资源还很充足;
load = 1 的时候就意味着桥已经被车给占满了,没有一点空隙,cpu 的已经在全力工作了,所有的资源都被用完了,当然还好,这还在能力范围之内,只是有点慢而已;
load > 1 的时候就意味着不仅仅是桥上已经被车占满了,就连桥外都被占满了,cpu 已经在全力工作,系统资源的用完了,但是还是有大量的进程在请求,在等待。若是这个值大于2、大于3,表示进程请求超过 CPU 工作能力的 2 到 3 倍。而若是这个值 > 5 说明系统已经在超负荷运作了。
|
1
2
3
4
5
|
# 查看物理CPU的个数
cat /proc/cpuinfo | grep "physical id" | sort | uniq | wc -l
# 查看物理CPU 0的核心数
cat /proc/cpuinfo | grep "physical id" | sort | grep "0" | uniq | wc -l
|
1
2
3
4
5
|
# Tasks: 26 total 进程总数
# 1 running 1 个正在运行的进程数
# 25 sleeping 25 个睡眠的进程数
# 0 stopped 没有停止的进程数
# 0 zombie 没有僵尸进程数
|
1
2
3
4
5
6
7
8
|
# Cpu(s): 1.0%us 用户空间进程占用 CPU 百分比
# 1.0% sy 内核空间运行占用 CPU 百分比
# 0.0%ni 用户进程空间内改变过优先级的进程占用 CPU 百分比
# 97.9%id 空闲 CPU 百分比
# 0.0%wa 等待输入输出的 CPU 时间百分比
# 0.1%hi 硬中断(Hardware IRQ)占用 CPU 的百分比
# 0.0%si 软中断(Software IRQ)占用 CPU 的百分比
# 0.0%st (Steal time) 是 hypervisor 等虚拟服务中,虚拟 CPU 等待实际 CPU 的时间的百分比
|
1
2
3
4
|
# 8176740 total 物理内存总量
# 8032104 used 使用的物理内存总量
# 144636 free 空闲内存总量
# 313088 buffers 用作内核缓存的内存量
|
1
2
3
4
|
# total 交换区总量
# used 使用的交换区总量
# free 空闲交换区总量
# cached 缓冲的交换区总量,内存中的内容被换出到交换区,而后又被换入到内存,但使用过的交换区尚未被覆盖
|
1
2
3
4
5
6
7
8
9
10
11
12
|
# PID 进程 id
# USER 该进程的所属用户
# PR 该进程执行的优先级 priority 值
# NI 该进程的 nice 值
# VIRT 该进程任务所使用的虚拟内存的总数
# RES 该进程所使用的物理内存数,也称之为驻留内存数
# SHR 该进程共享内存的大小
# S 该进程进程的状态: S=sleep R=running Z=zombie
# %CPU 该进程 CPU 的利用率
# %MEM 该进程内存的利用率
# TIME+ 该进程活跃的总时间
# COMMAND 该进程运行的名字
|
1
2
3
4
5
6
7
|
NICE 值叫做静态优先级,是用户空间的一个优先级值,其取值范围是-20 至 19。这个值越小,表示进程”优先级”越高,而值越大“优先级”越低。nice 值中的 -20 到 19,中 -20 优先级最高, 0 是默认的值,而 19 优先级最低
PR 值表示 Priority 值叫动态优先级,是进程在内核中实际的优先级值,进程优先级的取值范围是通过一个宏定义的,这个宏的名称是 MAX_PRIO,它的值为 140。Linux 实际上实现了 140 个优先级范围,取值范围是从 0-139,这个值越小,优先级越高。而这其中的 0 - 99 是实时进程的值,而 100 - 139 是给用户的。
其中 PR 中的 100 to 139 值部分有这么一个对应 PR = 20 + (-20 to +19),这里的 -20 to +19 便是 nice 值,所以说两个虽然都是优先级,而且有千丝万缕的关系,但是他们的值,他们的作用范围并不相同
** VIRT **任务所使用的虚拟内存的总数,其中包含所有的代码,数据,共享库和被换出 swap 空间的页面等所占据空间的总数
|
6.2 ps
工具
ps aux
# 列出所有进程信息
ps axjf
# 将连同父进程的所有子进程呈树状都列出来
ps -l
# 本次登录的bash相关进程
ps -afxo user,ppid,pid,pgid,command
# 列出所有进程信息,并且仅显示用户,父进程,进程,进程组,命令
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
# F 进程的标志(process flags),当 flags 值为 1 则表示此子程序只是 fork 但没有执行 exec,为 4 表示此程序使用超级管理员 root 权限
# USER 进程的拥有用户
# PID 进程的 ID
# PPID 其父进程的 PID
# SID session 的 ID
# TPGID 前台进程组的 ID
# %CPU 进程占用的 CPU 百分比
# %MEM 占用内存的百分比
# NI 进程的 NICE 值
# VSZ 进程使用虚拟内存大小
# RSS 驻留内存中页的大小
# TTY 终端 ID
# S or STAT 进程状态
# WCHAN 正在等待的进程资源
# START 启动进程的时间
# TIME 进程消耗 CPU 的时间
# COMMAND 命令的名称和参数
|
1
2
3
4
5
6
7
8
9
10
11
12
13
|
# R Running.运行中
# S Interruptible Sleep.等待调用
# D Uninterruptible Sleep.不可中断睡眠
# T Stoped.暂停或者跟踪状态
# X Dead.即将被撤销
# Z Zombie.僵尸进程
# W Paging.内存交换
# N 优先级低的进程
# < 优先级高的进程
# s 进程的领导者
# L 锁定状态
# l 多线程状态
# + 前台进程
|
1
|
其中的 D 是不能被中断睡眠的状态,处在这种状态的进程不接受外来的任何 signal,所以无法使用 kill 命令杀掉处于 D 状态的进程,无论是 kill,kill -9 还是 kill -15,一般处于这种状态可能是进程 I/O 的时候出问题了。
|
6.3 kill
命令
1
2
|
# 结束gedit的进程
ps -afxo pid,command | grep gedit | grep -E "[0-9]*" -o | xargs kill -9
|
7 Linux用户管理
7.1 查看用户
who
a
# 打印能打印的全部
d
# 打印死掉的进程
m
# 同am i,mom likes
q
# 打印当前登录用户数及用户名
u
# 打印当前登录用户登录信息
r
# 打印运行等级
1
2
3
4
5
6
7
|
# 查看当前登录的用户
who am i
# or
who mom likes
# 查看当前登录的用户名
whoami
|
1
2
|
# who am i的输出如下
root pts/1 2022-06-09 11:52 (172.18.0.2)
|
1
|
其中pts/1是伪终端,2022-06-09 11:52是登录时间。所谓“伪”是相对于/dev/tty设备而言的。
|
1
|
有一点需要注意的是,在某些环境中 who am i 和 who mom likes 命令不会输出任何内容,这是因为当前使用的 SHELL 不是登录时的 SHELL,没有用户与 who 的 stdin 相关联,因此不会输出任何内容。例如:可能如下图所示,输入这些命令却没有任何提示。
|
7.2 添加用户
adduser
# 该命令添加用户会在/home目录下自动创建用户的文件夹(创建用户的同时,会创建工作目录和密码)
useradd
# 只创建用户,不会创建用户密码和工作目录
1
2
3
4
5
6
7
8
9
10
|
```bash
# 添加用户
sudo adduser testme
# 修改用户密码
sudo passwd testme
# 切换用户
su -l testme
|
7.3 用户组
7.3.1 查看用户所属用户组
groups
# 查看用户所属的用户组
id
# 查看用户的UID和GID
1
2
3
4
5
|
# 查看testme用户所属的用户组
groups testme
# 查看/etc/group文件中testme的用户组信息
cat /etc/group | grep testme
|
1
2
|
# 输出如下
testme:x:1000:
|
/etc/group
的内容包括用户组(Group
)、用户组口令
、GID
(组 ID) 及该用户组所包含的用户(User
),每个用户组一条记录。格式如下:
group_name
:password
:GID
:user_list
1
2
3
|
上面的 password 字段为一个 x,并不是说密码就是它,只是表示密码不可见。
如果用户的 GID 等于用户组的 GID,那么最后一个字段 user_list 就是空的,这里的 GID 是指用户默认所在组的 GID,可以使用 id 命令查看。比如 shiyanlou 用户,在 /etc/group 中的 shiyanlou 用户组后面是不会显示的。lilei 用户,在 /etc/group 中的 lilei 用户组后面是不会显示的。
|
7.3.1 将用户添加到sudo用户组
1
2
|
# 在拥有root权限的用户下,将testme用户添加到sudo用户组
sudo usermod -G sudo testme
|
7.3.2 删除用户
1
2
|
# 删除用户testme,及其家目录
sudo deluser lilei --remove-home
|
7.3.3 删除及添加用户组
1
2
3
4
5
|
# 删除用户组testme
sudo groupdel testme
# 添加用户组testme
sudo groupadd testme
|
1
|
删除用户组可以使用 groupdel 命令,倘若该群组中仍包括某些用户,则必须先删除群组中用户后,才能删除群组。
|
7.3.4 更改用户家目录
1
2
|
# 更改testme用户家目录到/home/testme
sudo usermod -d /home/testme testme
|
7.4 Linux文件权限
1
2
3
4
5
6
7
8
9
10
11
12
13
|
# 使用testme用户在家目录创建文件test
su test
cd
touch test
# 以人类可读方式查看test文件信息
ls -ahl test
# 切换回root用户
exit
# 更改test文件的所有者为root用户
sudo chown root test
|
7.4.1 修改文件权限
1
2
3
4
5
|
# 修改test文件的所有者(root用户)的权限为读写(rw)
sudo chmod 600 test
# 修改test文件的所有者(root用户)及其他用户的权限为读写(rw)
sudo chmod 640 test
|
- 方式二:使用
chmod [权限组别] [+/-] [权限字母组合]
命令
1
2
3
4
5
|
# 修改test文件的所有者(root用户)的权限为读写(rw)
sudo chmod g+rw test
# 修改test文件的所有者(root用户)及其他用户的权限为读写(rw)
sudo chmod go+rw test
|
1
|
其中,g、o、u分别表示 group(用户组)、others(其他用户) 和 user(用户);+ 和 - 分别表示增加和去掉相应的权限。
|
1
2
|
# 修改test文件所有组为testme
sudo chgrp testme test
|
8 Shell
8.1 Shell的基本概念
8.1.1 Shell变量
1
2
3
4
5
|
# 正确的赋值
a=testme
# 错误的赋值
a = testme
|
1
2
3
4
5
6
|
# 循环语句赋值
for i in {1..10}
for file in `ls /home/testme`
for file in $(ls /home/testme)
|