arrange end

This commit is contained in:
e0x2d 2025-01-10 22:29:51 +08:00
parent 769ca8df25
commit 971a21a83d
71 changed files with 1477 additions and 642 deletions

404
OS/linux/command.md Normal file
View File

@ -0,0 +1,404 @@
# 基础命令
> sudo
> > 配置文件/etc/sudoers 使用visudo进行编辑
+ -u # 指定用户
> pwd
> cd
> ls
> > 列出目录下所有内容
+ -F # 在文件名后加提示符 '/' '*' '@'
+ -a # 显示隐藏文件
+ -l # 列出文件信息
+ -d # 目录
+ -h # 将文件大小输出为易读的格式
+ -s # 在行首显示(大小)?
+ -i # inode
# 文件目录操作管理
> cat
> >
+ -n # 显示行号
> less
> od
> > 查看非纯文本
+ -t # 类型 a, d, f, o, x
> grep
> > 文件字符串匹配
+ -A <n> # 后续n行
+ -B <n> # 前n行
+ -n # 显示行号
+ -v # 反向选择
+ -E 'o1|o2|o3' # 多匹配
> wc
> > 统计
+ -l 行数
+ -m 字符
+ -w
> mkdir
> touch
> mv
> >
+ -i # 覆盖时警告
+ -b # 重合加~
> cp
> > copy
+ -i # 覆盖时警告
+ -b # 重合加~
+ -u # 仅复制更新
+ -v # 详细显示
+ -r # 目录
> rm
> >
+ -i # 覆盖时警告
+ -r # 目录
+ -f # 强制
> chown
> > 所有权
+ -R # 同时更改所有子目录
> chmod
> > 权限修改
+ -R # 同时更改所有子目录
```bash
SUID 4
执行二进制文件时,权限提升为文件所有者
SGID 2
在此权限下的目录进入后,有效用户组变为所有组
SBIT 1
在此权限下的文件夹里创建文件仅有root与属主有权操作
```
> file
> > 观察文件类型
+ -i 查看编码格式
+ -z 查看压缩格式
+ -b 查看文件的系统架构
+ -p 详细信息
> umark
> > 设置默认权限,默认是拿掉权限
> ln
> > 链接(硬)
+ -s # 符号链接(软)
> diff
> > 比较文件
+ -b # 忽略空格
+ -i # 忽略大小写
+ -B # 忽略空白行
> patch
> > 补丁制作
> > example
```bash
diff -Naur <oldfile> <newfile> > <file.patch> # -p[n] 拿掉路径中的/
patch -p<n> < <file.patch> # 制作
patch -p<n>-R < <file.patch> # 还原
```
# 文件查找
> find
> > find [OPTION] [path] [expression]
+ -name [filename] # 指定文件名
+ -print # 打印结果在终端
+ -type [type] # 指定类型
+ -atime <+-n> # n天前使用的文件
+ -mtime <+-n> # n天前修改的文件
> > example
+ find /usr/bin -name zip -print
> locate
> whereis
> > 找命令文件
> which
> > 找PATH
+ -a # 全部列出
> whoami
> uname
> > 查看系统版本信息
+ -a 全部信息
# 文件压缩
> gzip
> >
+ -d # 解压
+ -l # 查看压缩效果
> bzip2
> >
+ -d # 解压
+ -l # 查看压缩效果
> xz
> >
+ -z # 压缩
+ -d # 解压
+ -l # 查看压缩效果
+ -k # 保留压缩原文件
+ -<number> # 压缩等级
+ -T <n> # 使用多个线程
+ -v # 显示详细过程
> tar
> > 文件打包
+ -c # 创建
+ -x # 解开
+ -v # 显示详细过程
+ -f <file> # 指定文件名
+ -z # 调用gzip
+ -j # 调用bzip2
+ -J # 调用xz
> > example
+ tar -cvjf shell.tar.bz2 shell/
> dd
> >
+ if # input file/device
+ of # output file/device
+ bs # one black size
+ count # *bs
# 磁盘
> mount
> > 挂载文件系统
+ -r # 只读
+ -o <loop> # 特殊设备
> > /etc/fstab 配置文件
+ auto # 开机自动挂载
+ noauto # 不自动挂载
+ ro # read only
+ rw # read and write
+ user # 任意用户可挂载
> > example
+ [设备/UUID] [挂载点] [文件系统] [参数] 0 0
> umount
> > 卸载文件系统
> df
> > 观察磁盘使用情况
> > example
+ df -hT
> sync
> smartctl
> > 查看硬盘状态参数
-a 全部参数
-H 是否正常
# 用户
> useradd
> >
+ -m # 同时建立主目录
+ -g # 指定用户组
+ -s # 指定shell
> groupadd
> passwd
> userdel
> >
+ -r # 删除主目录
> usermod
> >
+ -d # 修改主目录
+ -e <MM/DD/YY># 修改账号有效期
+ -s # 修改shell
> id
> > 查看用户信息
> /etc/passwd
> > example
+ 登录名:口令:UID:GID:x信息:主目录:shell
> /etc/group
> > example
+ 组名:组口令(一般无):GID:user1,user2,user3
### 用户所有组是passwd和groups的并集
> newgrp
> > 切换有效用户组
# 进程
> ps
> >
+ aux
> top
> lsop
> > 查看占用文件的进程
> kill
> > 发送信号
+ -l # 列出所有信号
> nice renice
> > 调整谦让度
# 网络
> ip
> >
> ss
> > 查看端口开放情况
+ -t # tcp
+ -u # udp
+ -n # 以端口号显示
+ -l # 列出正在监听的服务
+ -p # + pid
+` -r # 路由表
> > example
+ ss -tlunp
> ping
# 系统
> systemctl
> > systemctl [command] [unit]
+ start
+ stop
+ restart
+ reload
+ enable
+ disable
+ status
+ mask # 强制注销
+ unmask
> >
+ list-units
> >
+ get-default # 获取目前target
+ set-default # 设置默认target
+ isolate # 切换target
> > >
+ poweroff
+ reboot
+ suspend # 挂起
+ hibernate # 休眠
+ rescue # 修复
# 硬件
> dmidecode
> > 获取硬件信息
+ -q # 简洁
+ -t # 指定查看类型
# 软件包管理
> dpkg
> > .deb
+ -i # 安装
+ -l # 查看版本
+ -r # 卸载
> apt
> > apt-get
> > >
+ updata # 更新软件包缓存
+ upgrade # 更新已有软件包的最新版本
+ install # 下载并安装
+ remove # 卸载
+ source # 下载源码
> > apt-cache
> > >
+ search # 搜索
+ depends # 列出依赖
> > 配置源
+ /etc/apt/sources.list
# 其他命令
# nohup 命令挂机(退出登陆后依然执行)
nohup [command] &
`screen` 主要用于用户开启多个独立的会话(称为"窗口")在这些会话之间可以自由切换而不会中断已经运行的程序
### 主要功能:
1. **多会话管理**:可以同时运行多个独立的 shell 会话。
2. **会话分离与重连**:可以从一个会话中分离出来,稍后再重新连接到该会话。
3. **窗口分割**:在一个 screen 会话中,可以水平或垂直分割窗口,以同时查看和操作多个任务。
4. **滚动记录**:可以查看会话的滚动记录,即使之前的输出已经滚出屏幕。
5. **复制和粘贴**:在 screen 会话中,可以使用快捷键复制文本并粘贴到其他位置。
6. **会话锁定**:可以锁定当前会话,防止他人查看或操作。
7. **自动保存会话**在网络断开或其他异常情况下screen 可以自动保存当前会话状态。
### 基本使用方法:
1. **启动一个新的 screen 会话**
screen
2. **列出当前的 screen 会话**
screen -ls
3. **重新连接到一个已存在的会话**
screen -r [会话ID或名称]
4. **分离当前会话**
在 screen 会话中按 `Ctrl-a` 然后按 `d`
5. **在会话中创建新窗口**
在 screen 会话中按 `Ctrl-a` 然后按 `c`
6. **在窗口之间切换**
在 screen 会话中按 `Ctrl-a` 然后按 `n`(下一个窗口)或 `Ctrl-a` 然后按 `p`(上一个窗口)
7. **分割窗口**
- 水平分割:在 screen 会话中按 `Ctrl-a` 然后按 `"`(双引号键)。
- 垂直分割:在 screen 会话中按 `Ctrl-a` 然后按 `S`
8. **调整分割窗口的大小**
- 增加/减少水平大小:在 screen 会话中按 `Ctrl-a` 然后按方向键。
- 增加/减少垂直大小:在 screen 会话中按 `Ctrl-a` 然后按 `Shift` 加上方向键。
9. **退出 screen 会话**
- 关闭当前窗口:在 screen 会话中按 `Ctrl-a` 然后按 `k`
- 退出所有窗口并结束会话:在 screen 会话中按 `Ctrl-a` 然后按 `\`
10. **锁定当前会话**
在 screen 会话中按 `Ctrl-a` 然后按 `x`
# ulimit
查看和修改进程运行资源限制
-H/S # 设置/显示 软/硬 限制
-a # 显示所有
-t # cpu time
-f # file size
-s # stack size
-c # core file size
-m # memory size
-l # lock memory size
-p # user processes
-n # open file
#ulimit -Ht 3600

View File

@ -0,0 +1,72 @@
# /
根目录
# /bin
存放基本的用户命令和系统命令
# /sbin
系统管理员用的系统命令
# /boot
启动所需的内核等
# /dev
设备文件
# /etc
系统配置文件
# /home
用户家目录
# /lib
系统库
# /media
挂载可移动介质
# /mnt
临时挂载文件系统
# /proc
虚拟文件系统
# /root
root家目录
# /tmp
临时文件
# /opt
存放可选的第三方软件
# /usr 存放不经常变动的程序和文件
> /usr/bin
用户级程序
> /usr/sbin
> /usr/include
> /usr/lib
> /usr/share
共享数据文件
> /usr/src
存放源码
# /var 存放经常变动的文件
> /var/log
> /var/mail
> /var/run
系统运行的临时文件
# /run
类似 /var/run 但是重启时不会清空
# /sys
虚拟文件系统,包含硬件信息,比 /proc 更易访问

240
OS/linux/knowledge/elf.md Normal file
View File

@ -0,0 +1,240 @@
# [ELF文件格式]
ELF是程序文件的一种类型它并非由Linux研发但Linux采用这种类型管理程序文件具体又分为以下四类
1. 可执行文件,可以自己在操作系统中执行的程序。
2. 可重定向文件,不能自己在操作系统中执行的程序,其只有程序本身的数据,没有操作系统识别其各种属性以及辅助执行的数据,需要使用连接器添加属性信息、以及辅助执行代码制作为可执行文件才能在操作系统中执行,或用于被其它程序调用,与其它程序一起组合为可执行文件。
3. 动态连接库文件,类似可重定向文件,不能自己执行,需要被其它程序调用执行,但是在执行期间与其组合为一体
4. 核心转储文件,进程执行出错后操作系统将其终止执行,同时将进程在内存中的数据保存一份到辅存,用户可以读取核心转储文件查询进程终止前的执行状态与终止原因。
__静态连接库不归类于ELF文件__
## ELF文件内的数据可以分为四类
1. 文件头,文件内容起始数据,用于说明文件类型、文件属性。
2. 程序节属性表,同节属性表,但只用于存储指令数据节、指令执行相关节的属性
3. 节英文名为section也有人称为段程序的指令数据、数学数据、运行相关属性数据会按作用分为多组每一组使用一个节存储。
4. 节属性表,是一个元素为结构体的数组,每个元素存储一个节的属性信息。
### 文件头
文件头使用一个结构体定义以64位ELF文件为例文件头原型如下
```c
typedef struct
{
unsigned char e_ident[16];
//前4个字节数据分别为7f 45 4c 46第一个字节为删除键编码、后三个字节为ELF字母的编码表示这是ELF文件
//第5个字节说明ELF文件运行在32位处理器还是64位处理器值为1表示32位值为2表示64位
//第6个字节说明数学数据使用的字节序值为1表示小端序值为2表示大端序
//第7个字节说明ELF文件的版本目前只能设置为1
//第8个字节指定程序使用的ABI的类型通常设置为0
//第9个字节指定程序使用的ABI的版本通常设置为0
//第10-16字节保留不用全部赋值为0
u16 e_type; //指定ELF文件的具体类型值为1-41表示可重定向文件2表示可执行文件3表示动态连接库4表示核心转储文件
u16 e_machine; //指定程序使用的CPU类型值为62表示64位X86处理器值为40表示32位ARM处理器值为183表示64位ARM处理器
u32 e_version; //指定ELF文件的版本目前只有一个版本值固定为1
u64 e_entry; //指定程序执行入口虚拟地址虚拟地址从0x400000开始算起若为可重定向文件、动态连接库则此值为0
u64 e_phoff; //指定程序节属性表的文件内部地址文件内部地址从0开始分配文件头占用最开始的地址程序节属性表在之后若e_phoff为0表示不包含程序节属性表
u64 e_shoff; //指定节属性表的文件内部地址若为0表示不包含节属性表
u32 e_flags; //程序运行在特殊处理器中时使用此数据设置某些信息运行在x86处理器中时此数据设置为0
u16 e_ehsize; //文件头的长度,以字节为单位
u16 e_phentsize; //程序节属性表的元素长度,以字节为单位
u16 e_phnum; //程序节属性表的元素数量
u16 e_shentsize; //节属性表的元素长度,以字节为单位
u16 e_shnum; //节属性表的元素数量
u16 e_shstrndx; //指定节属性表中哪个元素存储shstrtab节信息值为元素下标
} Elf64_Ehdr;
```
+ e_ident的第8-9个字节设置ABI信息ABI全称为Application Binary Interface中文名为应用程序二进制接口它是一组规则的名称是操作系统为程序制定的运行规则比如多字节数据排序方式、函数调用时参数如何传递、函数返回值如何存储、系统调用使用规则、异常功能使用规则CPU在设计时会为了兼容ABI的某些规则进行优化提升程序运行速度
#### 一个 x86-64 ELF 可执行文件的文件头
```
7F 45 4C 46 02 01 01 00 00 00 00 00 00 00 00 00 //e_ident
02 00 3E 00 01 00 00 00 //e_type - e_version
40 10 40 00 00 00 00 00 //e_entry
40 00 00 00 00 00 00 00 //e_phoff
18 39 00 00 00 00 00 00 //e_shoff
00 00 00 00 40 00 38 00 //e_flags - e_phentsize
0B 00 40 00 1D 00 1C 00 //e_phnum - e_shstrndx
```
### 程序节属性表
+ 程序节属性表紧邻文件头,是一个数组,元素为结构体,专用于存储程序节的属性
```c
typedef struct
{
u32 p_type; //指定节的类型
u32 p_flags; //设置节的访问权限最低位设置执行权限、第2位设置写权限、第3位设置读权限对应位设置为1表示有此权限指令节设置为可执行全局变量节设置为可读可写全局常量节设置为只读
u64 p_offset; //节的文件内部地址
u64 p_vaddr; //节的虚拟地址
u64 p_paddr; //节的内存物理地址某些特殊操作系统需要使用在linux中不使用此数据
u64 p_filesz; //ELF文件在辅存中存储时此节的长度
u64 p_memsz; //ELF文件读取到内存中时此节的长度有些节只在程序执行时才会存储数据比如.bss节这种节只在内存中分配存储空间
u64 p_align; //节的内存地址对齐值若值为0或1等同于无对齐要求
}Elf64_Phdr;
```
```
06 00 00 00 04 00 00 00 //p_type、p_flags
40 00 00 00 00 00 00 00 //p_offset
40 00 40 00 00 00 00 00 //p_vaddr
40 00 40 00 00 00 00 00 //p_paddr
68 02 00 00 00 00 00 00 //p_filesz
68 02 00 00 00 00 00 00 //p_memsz
08 00 00 00 00 00 00 00 //p_align
```
### 节
__动态连接相关__
```
.interp存储动态库加载器的路径是一个字符串ELF可执行文件才有此节。
.dynsymDynamic Symbol存储动态库全局成员的属性类似.strtab。
.dynstrDynamic String存储动态库全局成员的名称每个名称都是以空字符结尾的字符串同时此节的第一个字节也定义为空字符。
```
__指令数据节__
```
.init存储程序执行入口指令用于程序执行前的基础初始化工作代码由编译器自动生成之后跳转到.text节执行存储指令数据的节会被操作系统设置为只读。
.pltprocedure linkage table调用动态库内数据相关内部是由编译器生成的多个汇编代码模块。
.text存储程序主体功能代码程序执行前复杂的初始化工作代码在这里编译器生成用户自己编写的代码也存储在这里。
.fini存储程序终止时执行的相关代码代码由编译器生成
```
__数学数据节__
```
.rodata存储全局常量此节分配的内存页会被操作系统设置为只读。
.init_array存储一组函数地址这些函数会在main函数之前执行。
.fini_array存储一组函数地址这些函数会在main函数之后执行。
.dynamic存储操作系统将程序加载到内存执行时需要使用的某些信息比如程序需要使用哪些动态库、某些节的虚拟地址具体数据的含义可使用 readelf -d 命令查看。
.gotglobal offset table主要存储glibc两个函数的地址__gmon_start__、__libc_start_main此地址在ELF文件中存储0程序执行时操作系统将gilbc读取到内存之后将函数的具体地址写入.got。
.data存储定义时已赋值的全局变量。
.bss存储定义时未赋值的全局变量编译后的文件此节不占用存储空间程序读取到内存执行时才会为此节分配存储空间此节占用的内存单元会全部设置为0定义全局变量不赋值的话初始值为0
```
__编译器相关__
```
.comment存储编译器版本信息内部是一个字符串
```
__调试相关__
```
.debug存储调试程序时需要的相关信息供调试器使用比如数据的类型、指令数据对应的高级语言源代码行号使用gcc编译程序时添加 -g 参数会生成此节。
```
__全局成员相关__
```
.symtabsymbol table程序中的全局变量、全局常量、函数这三者统称为symbol有人将其翻译为符号鉴于这种翻译完全不合理这里将其称为全局成员.symtab节用于存储所有全局成员的属性信息比如数据类型、数据长度、成员名称实际存储的是数据名在.strtab节的位置、成员是否可被外部程序调用每个全局成员的属性使用一个Elf64_Sym结构体存储所有的Elf64_Sym结构体组成一个数组这个数组就是.symtab节。
.strtabstring table存储全局成员symbol的名称对程序进行调试和反汇编时看见的数据名由此节记录使用gcc编译程序时可以添加-s参数不保留这些数据名。对于C语言程序此节记录的是数据名原型对于C++程序此节记录的并非原始数据名因为C++支持函数重载、符号重载、虚拟类型、命名空间,导致多个数据可以同名,编译器会在原始数据名的前后分别添加随机字符从而区分同名数据,另外类成员、命名空间成员还会包含类名、命名空间名
```
__节名相关__
```
.shstrtab存储其它节的名称为节设置名称是编译器的工作使用gcc编译程序时添加-s参数将不会生成节名称
```
### 节属性表
`程序节之外的节使用Elf64_Shdr结构体存储其属性每个节的属性称为 section headers简称sh所有的 section headers 组合为节属性表。`
```c
typedef struct
{
u32 sh_name; //存储本节的名称在shstrtab节中的位置若为0则表示此节没有名称
u32 sh_type; //节的类型,常用值如下:
//SHT_NULL值为0无效节
//SHT_PROGBITS值为1存储程序运行所用数据的节比如.text、.data、.rodata不包含.bss
//SHT_SYMTAB值为2.symtab节
//SHT_STRTAB值为3字符串表包括 .strtab .shstrtab .dynstr
//SHT_RELA值为4.rela节
//SHT_HASH值为5.hash节
//SHT_DYNAMIC值为6.dynamic节
//SHT_NOTE值为7此节包含一些注释信息
//SHT_NOBITS值为8此节不在ELF文件中而是在程序执行期间分配内存空间比如.bss
//SHT_REL值为9.rel节
//SHT_SHLIB值为10保留节具体含义未定义
//SHT_DYNSYM值为11.dynsym节
u64 sh_flags; //节的访问权限
u64 sh_addr; //节的虚拟地址若为0则程序执行时此节不会读取到内存中因为这些节只起辅助作用
u64 sh_offset; //节的文件内部地址
u64 sh_size; //节的长度,单位为字节
u32 sh_link; //节属性表中另一个元素的下标连接器有时需要知道两个节的联系若不需要与另一个节有关联则设置为0
u32 sh_info; //附加信息
u64 sh_addralign; //节的内存地址对齐值若值为0或1则表示无对齐要求
u64 sh_entsize; //有些节的内容是一个数组此成员存储数组元素的长度若节的内容不是数组则设置为0
} Elf64_Shdr;
```
```
// 一个 x86-64 ELF 可执行文件的 .shstrtab 节属性信息:
11 00 00 00 03 00 00 00 //sh_name - sh_type
00 00 00 00 00 00 00 00 //sh_flags
00 00 00 00 00 00 00 00 //sh_addr
2d 38 00 00 00 00 00 00 //sh_offset
03 01 00 00 00 00 00 00 //sh_size
00 00 00 00 00 00 00 00 //sh_link - sh_info
01 00 00 00 00 00 00 00 //sh_addralign
00 00 00 00 00 00 00 00 //sh_entsize
```
## RIP相对寻址
`在x86处理器中指令使用32位内存地址读写内存在x86-64处理器中指令使用64位内存地址读写内存64位处理器的mov指令使用直接内存寻址的方式读写内存数据时若使用立即数存储要操作的内存地址则指令长度会超标指令操作码 + 8字节内存地址 + 寄存器编号或4字节立即数为此x86-64新增了一种内存寻址方式称为RIP相对寻址其让RIP寄存器增加一个值得出要操作的内存地址就像跳转指令使用IP寄存器加一个立即数得出要跳转到的地址一样`
`RIP相对寻址用于程序的全局数据寻址局部数据在栈中存储栈空间数据不使用rip相对寻址而是使用rsp、rbp确定要操作的地址`
```c
#include <stdio.h>
int a = 1;
int main()
{
a = 9;
printf("%d\n", a);
return 0;
}
```
```asm
0000000000401122 <main>:
401122: 55 push rbp
401123: 48 89 e5 mov rbp,rsp
401126: c7 05 00 2f 00 00 09 00 00 00 mov DWORD PTR [rip+0x2f00],0x9 ;调用变量a地址404030rip现值 = 0x4011300x401130 + 0x2f00 = 0x404030
401130: 8b 05 fa 2e 00 00 mov eax,DWORD PTR [rip+0x2efa] ;变量a写入eax
401136: 89 c6 mov esi,eax
401138: bf 04 20 40 00 mov edi,0x402004
40113d: b8 00 00 00 00 mov eax,0x0
401142: e8 e9 fe ff ff call 401030 ;调用printfrip加-0x117补码向前跳转到0x401030
401147: b8 00 00 00 00 mov eax,0x0
40114c: 5d pop rbp
40114d: c3 ret
Contents of section .data:
404020 00000000 00000000 00000000 00000000
404030 01000000
```
地址401126处的mov指令长度10字节分别如下
操作码2字节值为 05 c7。
地址码14字节存储rip要加的数据定位到操作的内存单元值为 00 00 2f 00。
地址码24字节存储要写入的立即数值为 00 00 00 09。
rip与一个4字节有符号数相加总共可以寻址约4GB内存空间前后各2GB。

View File

@ -0,0 +1,24 @@
# linux键盘高级操作技巧
> 光标移动
+ C a # 到行首
+ C e # 到行末
+ C f # 下一个字符
+ C b # 上一个字符
+ C l # clean
+ A f # 下一个词
+ A b # 上一个词
> 文本修改
+ C t # 与上一个字符互换
+ A t # 与上一个词互换
> 批量处理
+ C k # 剪切到行尾
+ C u # 剪切到行首
+ C y # 粘贴
> 命令
+ C p # 上一个命令
+ C n # 下一个命令
+ C j # 复制
+ C o # 执行当前项,并移到下一项

View File

@ -2,4 +2,5 @@ cmd //cmd
dxdiag //电脑配置
mrt //清理恶意软件
cleanmgr //清理磁盘
regedit //使用注册表
regedit //使用注册表
shell:RecycleBinFolder

View File

@ -13,6 +13,7 @@ ipconfig /flushdns // 清空DNS缓存
nslookup //查询任何一台机器的IP和对应的域名
netstat //显示活动的TCP连接计算机侦听的端口以太网统计信息IP路由表IPv4统计信息以及IPv6统计信息
powercfg -h off //关闭休眠可节省C盘空间
shutdown /r /fw /t 0 // 重启到BIOS
-----------------------------------------------------------------------------
windows控制台命令 大集合

20
OrdinaryHeroChronicles.md Normal file
View File

@ -0,0 +1,20 @@
# 谨以此表,以记平凡的英雄们
# 华中农业大学学术造假事件发起联合举报的11位学子
黄飞若教授学术造假
2024年1月16日 11位学生联合举报黄飞若为首的学术造假事件
虽螳臂当车吾亦往矣(举报pdf结语)
星星之火,可以燎原,把这枚火种,传下去!
# 雨希不想画画 up 2006/11/9--2024/2/22
2024年2月21日下午5点54分
放学后外出吃饭的过程中为救一位小孩被车碾压,次日抢救无效离世
被救的小朋友并无生命危险,仅伤到腿
雨希以生命为代价救下了这位小朋友
# 永城市实验高级中学5.14事件全体学生
2015年5月14日
起因 食堂条件差,且食堂经理殴打买茶叶蛋师娘,校领导不作为
学生强烈抗议,打砸食堂
事件过后领头学生被叫到校领导办公室处置,学生发起二次冲锋
结果 校领导被撤销党内职务,行政撤职处分

19
README.md Normal file
View File

@ -0,0 +1,19 @@
存放计算机类笔记的仓库
======================
## 使用说明以及环境
+ 今后我尽量改写成makedown的文本
## 项目结构
## 更新连接
## 历史版本 Histroy
## 作者列表 AUTHORS
+ ely

View File

@ -1,64 +0,0 @@
// 示例客户端程序
// 发送文件到服务端
#include <iostream>
#include <fstream>
#include "tn.h"
using namespace std;
struct FileStat { //存放文件信息
char name[128]; // 文件名
size_t fsize = 0, read = 0, ssize = 0;
//文件大小 文件已读大小 本次发送大小
};
int pton(char *, const char *);
int file_out(TN &, char *); // 传入一个连接和文件路径
int main(int argc, char *argv[]) {
if(argc != 2) {
cout << "Using: ./cli.exe 文件名" << endl;
return 0;
}
TN test1;
if(test1.client("127.0.0.1","12345")!=0)
return 0;
cout << "连接已成功" << endl;
cout << file_out(test1, argv[1]) << endl;
cout << "连接断开" << endl;
return 0;
}
int pton(char *name, const char *path) {
int ptr = strlen(path);
while(ptr!=0 && path[ptr-1]!='/')
ptr--;
for(int j=0; ptr<=strlen(path); j++,ptr++)
name[j]=path[ptr];
return 0;
}
int file_out(TN &tn, char *path) { // 传入一个连接和文件路径
const unsigned int BSIZE = 1024;
char buffer[BSIZE];
FileStat fs;
fstream fin(path, ios::in|ios::binary);
pton(fs.name, (const char *)path);
fin.seekg(0, ios::end);
fs.fsize = fin.tellg();
fin.seekg(0, ios::beg);
// 发送信息
if(tn.out((FileStat *)&fs, sizeof(fs))!=0) return 0;
if(tn.in((char *)buffer)!=0) return 0; // 接收确认报文
// 正式发送文件
while(fin.good() && fs.fsize>fs.read) {
memset(buffer, 0, sizeof(buffer));
fs.ssize = (fs.fsize-fs.read)>BSIZE? BSIZE:(fs.fsize-fs.read);
fin.read(buffer, fs.ssize);
if(tn.out(buffer, fs.ssize)!=0) return -1;
fs.read += fs.ssize;
}
fin.close();
return 0;
}

View File

@ -1,5 +0,0 @@
main: ser.o cli.o tn.o
g++ -o ser.exe ser.o tn.o
g++ -o cli.exe cli.o tn.o
clear:
rm *.o *.exe

View File

@ -1,110 +0,0 @@
```cpp
#include <iostream>
#include <cstring>
#include <unistd.h>
#include <netdb.h>
#include <cstdlib>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
```
# tips
+ 所有网络函数失败基本是返回 -1,errno被设置
# socket
原型: int socket(int domain, int type, int protocol)
+ domain 协议族
\ PF_INET # IPv4 互联网协议族
\ PF_INET6 # IPv6 互联网协议族
\ PF_LOCAL # 本地通讯地址族
+ type 数据传输类型
\ SOCK_STREAM # 面向连接; 数据不丢失; 数据顺序不错乱; 双向通道;
\ SOCK_DGRAM # 无连接; 数据可能丢; 数据可能错乱; 效率高;
+ protocol 最终使用协议
\ IPPROTO_TCP
\ IPPROTO_UDP
\ 0 # 编译器自动识别
# 主机字节序和网络字节序
+ 大端序和小端序 (如果数据大于1B,CPU在内存中存放数据的方式)
\ 大端序 低位字节在高位,高位字节在低位
\ 小端序 低位字节在低位,高位字节在高位 (INTEL)
## 字节序不同的系统字节传输数据,可能会出现问题,所以网络字节序约定使用大端序
+ c提供了4个库用于主机字节序和网络字节序之间的转换
\ uint16_t htons(uint16_t hostshort); // 2字节的整数
\ uint32_t htonl(uint32_t hostshort); // 4字节的整数
\ uint16_t ntons(uint16_t netshort); // 2字节的整数
\ uint32_t ntonl(uint32_t netshort); // 4字节的整数
// h host主机
// to 转换
// n network网络
// s short(2byte)
// l long(4byte)
# IP地址和通讯端口
+ IPv4(4byte) 端口(2byte)
# 大小端序的处理
+ 在网络编程中数据收发有自动转换,只有sockaddr_in结构成员变量填充数据时才需要考虑字节序
# 结构体
## sockaddr
```cpp
struct sockaddr { // connect() bind() 都需要
unsigned short sa_family; // 协议族
unsigned char sa_data[14]; // 14byte的端口和地址
}
```
## sockaddr_in
```cpp
struct sockaddr { // 为了方便操作大小与sockaddr相同可以强制转换
unsigned short sin_family; // 协议族
unsigned short sin_port; // 2byte端口号
//struct in_addr sin_addr; // 4byte地址
unsigned int sin_addr; // 4byte地址
unsigned char sin_zero[8]; // 保留,长度对齐
}
```
# gethostbyname函数
+ 用 域名/主机名/字符串IP 转换成大端序
```cpp
struct hostent *gethostbyname(const char *name);
struct hostent {
char *h_name; // 主机名
char **h_aliases; // 主机所有别名的字符串数组
short h_addrtype; // 主机IP类型,IPv4或IPv6
short h_length; // 主机IP长度
char **h_addr_list; // 主机IP地址,以网络字节序存储
}
#define h_addr h_addr_list[0]
// 转换后,用 memcpy(&servaddr.sin_addr, h->h_addr, h->h_length);
```
# 字符串IP和大端序IP的转换
## atoi() 把字符串IP转换成大端序
```cpp
typedef unsigned int in_addr_t; //4byte大端序IP
// 字符串转大端序IP,转换后IP赋给sockaddr_in.in_addr.s_addr
in_addr_t inet_addr(const char *cp);
// 字符串转大端序IP,转换后IP赋给sockaddr_in.in_addr
int inet_aton(const char *cp, struct in_addr *inp);
//大转字符串,用于服务端解析IP
char *inet_ntoa(struct in_addr in);
```

View File

@ -1,61 +0,0 @@
// 示例服务端程序
// 一个可以接收文件的服务端程序
#include <iostream>
#include <fstream>
#include "tn.h"
using namespace std;
struct FileStat { //存放文件信息
char name[128]; // 文件名
size_t fsize = 0, read = 0, ssize = 0;
//文件大小 文件已读大小 本次发送大小
};
int pton(char *, const char *);
int file_in(TN &, char *); // 传入一个连接和文件保存目录
int main(int argc, char *argv[]) {
if(argc != 2 || (argv[1][strlen(argv[1])-1]!='/')) {
cout << "Using: ./ser.exe [PATH]/" << endl;
return 0;
}
TN test1;
test1.server("12345", 10);
cout << "客户端连接成功" << endl;
cout << file_in(test1, argv[1]) << endl;
cout << "客户端连接断开" << endl;
return 0;
}
int pton(char *name, const char *path) {
int ptr = strlen(path);
while(ptr!=0 && path[ptr-1]!='/')
ptr--;
for(int j=0; ptr<=strlen(path); j++,ptr++)
name[j]=path[ptr];
return 0;
}
int file_in(TN &tn, char *path) { // 传入一个连接和文件保存目录
const unsigned int BSIZE = 1024;
char buffer[BSIZE];
FileStat fs;
fstream fout;
memset(buffer, 0, sizeof(buffer));
strcpy(buffer, path);
if(tn.in((FileStat *)&fs, sizeof(fs))!=0) return 0; // 接收文件信息
strcat(buffer, fs.name); // 连接字符串
// strcpy(fs.name, buffer);
fout.open(buffer, ios::out|ios::trunc|ios::binary); // 打开保存文件
if(tn.out((char *)"OK")!=0) return 0; // 发送确认报文
while(fout.good() && fs.fsize>fs.read) {
memset(buffer, 0, sizeof(buffer));
fs.ssize = (fs.fsize-fs.read)>BSIZE? BSIZE:(fs.fsize-fs.read);
if(tn.in(buffer, fs.ssize)!=0) return -2;
fout.write(buffer, fs.ssize);
fs.read += fs.ssize;
}
fout.close();
return 0;
}

View File

@ -1,119 +0,0 @@
#include "tn.h"
using namespace std;
TN::TN() {
iofd = listenfd = 0;
}
TN::~TN() {
close(listenfd); //关闭连接
close(iofd); //关闭连接
}
int TN::server(const char *open_port, int connections) {
// 创建服务端socket
listenfd = socket(AF_INET, SOCK_STREAM, 0);
if(listenfd == -1)
return -1;
// 向客户端请求连接
memset(&servaddr, 0, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htons(INADDR_ANY);
servaddr.sin_port = htons(atoi(open_port)); //指定连接端口
// 解决端口重用问题
int opt = 1;
setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof opt);
// 绑定服务端IP及端口
if(bind(listenfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) != 0)
return -1; // 绑定失败
// 把端口设为监听
if(listen(listenfd, connections) != 0) //第二个参数+1为已连接队列(已三次握手但没有accept)
return -1;
return s_accept();
}
int TN::client(const char *ip, const char *port) {
// 创建客户端socket
iofd = socket(AF_INET, SOCK_STREAM, 0);
if(iofd == -1)
return -1;
// 向服务端请求连接
if( (h = gethostbyname(ip)) == 0) // 指定ip地址
return -1;
memset(&servaddr, 0, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(atoi(port)); //指定连接端口
memcpy(&servaddr.sin_addr, h->h_addr, h->h_length);
if(connect(iofd, (struct sockaddr *)&servaddr, sizeof(servaddr)) != 0) //发起连接请求
return -1; //连接失败
return 0;
}
int TN::s_accept() {
// 受理客户端连接请求, accept()阻塞等待
signal(SIGINT, TN_exit);signal(SIGTERM, TN_exit);
while(true) {
iofd = accept(listenfd, 0, 0);
if(iofd == -1) {
close(iofd); return -1; // 连接失败
}
int pid = fork();
if(pid == 0) { // 创建子进程处理连接
signal(SIGINT, SIG_IGN); signal(SIGTERM, SIG_DFL);
close(listenfd);
break;
}
else if(pid < 0) return -1;
else close(iofd);
}
return 0;
}
int TN::out(char *str) {
if(send(iofd, str, strlen(str), 0) <= 0) // 发送报文
return -1; // 报文发送不成功
return 0;
}
int TN::in(char *str) {
//接收报文, recv()将阻塞等待
memset(str, 0, sizeof(str));
if(recv(iofd, str, sizeof(str), 0) <= 0)
return -1; // 未成功接收报文
return 0;
}
int TN::out(void *str, size_t fsize) {
if(send(iofd, str, fsize, 0) <= 0) // 发送报文
return -1; // 报文发送不成功
return 0;
}
int TN::in(void *str, size_t fsize) {
//接收报文, recv()将阻塞等待
memset(str, 0, fsize);
if(recv(iofd, str, fsize, 0) <= 0)
return -1; // 未成功接收报文
return 0;
}
socklen_t TN::bufsize(size_t buf_send, size_t buf_recv) {
socklen_t optlen = sizeof(buf_send);
// 接收缓冲区大小
getsockopt(iofd, SOL_SOCKET, SO_SNDBUF, &buf_send, &optlen);
// 发送缓冲区大小
getsockopt(iofd, SOL_SOCKET, SO_RCVBUF, &buf_recv, &optlen);
return optlen;
}
int TN::nagle_off() {
int opt = 1;
setsockopt(iofd, IPPROTO_TCP, TCP_NODELAY, &opt, sizeof(opt));
return 0;
}
void TN_exit(int sig) {
signal(SIGTERM, SIG_IGN); signal(SIGINT, SIG_IGN); //避免再次干扰
kill(0, SIGTERM); // 通知所有子进程退出
exit(0);
}

View File

@ -1,64 +0,0 @@
// Copyright (c) 2024 ely. All rights reserved.
// simple_TcpNet
// 宗旨:简单易用,且尽可能的自由
// versions 1.0.2
// 大版本 小版本 修订版本
#ifndef TCPNET
#define TCPNET
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <unistd.h>
#include <netdb.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <signal.h>
#include <netinet/tcp.h>
class TN { // tcp socker net
private:
int iofd, listenfd;
struct hostent* h;
struct sockaddr_in servaddr;
int s_accept();
public:
TN();
~TN();
int server(const char *, int);
// 服务端的初始化函数
// 传入一个使用的端口号(请尽量用大于1024的值)和最大等待连接数
// 服务端受理并处理连接,使用多进程以连接多个客户端
// 若返回0表示成功与一个客户端建立连接
int client(const char *, const char *);
// 客户端的初始化函数
// 参数为服务端ip和端口
// 若返回0表示成功与一个服务端建立连接
// 网络I/O函数 在连接建立后即可使用此组函数进行通信
int out(char *);
int in(char *);
// 重载的任意类型IO函数第二个参数是类型大小
int out(void *, size_t);
int in(void *, size_t);
// 查看socket发送和接收缓冲区的大小
socklen_t bufsize(size_t buf_send, size_t buf_recv);
// 禁用Nagle算法,可以减少延迟,但是带宽利用不充分
int nagle_off();
};
void TN_exit(int sig);
#endif
/*
HISTORY
1.0.1
1.0.2 bufsize函数查看缓冲区大小 nagle_off开关
PLAN
*/

View File

@ -0,0 +1,24 @@
# function 包装器
提供更加一致的接口,避免多次实例化
对于调用特征标(call signature)一样的函数使用function进行包装
```cpp
std::function<double(int)> fun1;
```
+ 可接受任何函数指针函数对象lambda表达式
```cpp
template <typename T>
void print(T f, int a) {
std::cout << f(a) << std::endl;
}
double f1(int a) {
return a/1.0;
}
std::function<double(int)> fun1=f1;
print(fun1, 10);
```

View File

@ -1,118 +1,90 @@
#include <iostream>
#include <cstring>
using namespace std;
# string 字符串模板
void c_char(const char *,const char *);
void c_string(const char *,const char *);
`#include <string>`
int main() {
char a[1000],b[1000];
cin >> a >> b; // 流读入
c_char(a, b); //c风格字符串
c_string(a, b); //string
return 0;
}
void c_char(const char *str1,const char *str2) {
char buf1[1000],buf2[1000];
printf("c风格字符串\n\n");
strcpy(buf1, str1); strcpy(buf2, str2);
strcpy(buf1, "hello"); // 用后面的字符串覆盖前面的字符串
strncpy(buf1, "hello", 5); // 增加指定长度
strcat(buf1, "hello"); // 连接字符串
strncat(buf1, "hello", 5);
strcmp(buf1, "hello"); // 比较字符串,相等返回0
strlen(buf1); // 返回长度,不包括'\0'
strstr(buf1, "hello"); // 返回第一次出现子串的指针
strtok(buf1, " "); // 分割字符串,返回分割过的字符串
memset(buf1, 0, sizeof(buf1));//覆写内存块
memcpy(buf1, "hello", 5); //复制内存块
memmove(buf1 + 1, buf1, 4); //移动5个字节到前一个位置
}
void c_string(const char *str1, const char *str2) {
string buf;
/*
// 构造
## 构造
```cpp
string(); // 默认构造,创建一个空的字符串
string(const char &str1); // c风格字符串初始化
string(int n,char c); // 用字符填充一个字符串
```
// 赋值
## 赋值
```cpp
string& operator=(const char* str1); // c风格字符串赋值给当前string类
string& operator=(const string& buf); // 另一个容器复制
string& operator=(const cahr c); // 字符赋值
```
// 存取
## 存取
```cpp
char& operator[](int n); // 通过[]获取字符,注意溢出
```
// 拼接
## 拼接
```cpp
string& operator+=(const string& str); // 追加到末尾
string& operator+=(const char* str); // 追加到末尾
string& operator+=(const char c); // 追加到末尾
```
// 查找
## 查找
```cpp
int find(const string& str, int pos = 0) const; // 查找str在当前字符串第一次出现的位置,pos为开始查找的位置
int find(const char* str, int pos = 0) const; // 查找str在当前字符串第一次出现的位置
int rfind(const char* str, int pos = npos) const; // 查找str在当前字符串第一次出现的位置,反向查询
string::npos 在值上等于-1 即size_t的最大值 表示直到字符串结束
```
// 替换
## 替换
```cpp
string& replace(int pos, int n, const string& str); // 从pos开始替换n个字符
string& replace(int pos, int n, const char* str); // 从pos开始替换n个字符
```
// 比较
## 比较
```cpp
int compare(const string& str) const; //根据字典序
int compare(const char* str) const; //根据字典序
各种比较操作符都有重载
```
// 子串
## 子串
```cpp
string substr(int pos = 0, int n = npos) const; //返回从pos开始,长度为n的子串
```
// 插入
## 插入
```cpp
string& insert(int pos, const char* str); //在pos位置插入
string& insert(int pos, const string& str); //在pos位置插入
string& insert(int pos, int n, char c); //在pos位置插入
string& insert(int pos, int n, char c); //在pos位置插入
```
// 删除
## 删除
```cpp
string& erase(int pos, int n = npos); //在pos位置插入
```
# 两种转换
## 两种转换
```cpp
string str1;
const char* str2 = str1.c_str();
const char* str3;
string str4(str3);
```
# 神奇转换函数
## 神奇转换函数
```cpp
string to_ strinf(任何类型); //将好多类型转换成string
*/
}
```

View File

@ -1,7 +0,0 @@
#include <stdio.h>
int main(int argv, char *argc[]) {
printf("传入了 %d 个参数\n",argv);
for(int i = 0; i < argv; i++)
printf("第%d个参数: %s\n",i+1,argc[i]);
return 0;
}

33
c++/universal/c_string.md Normal file
View File

@ -0,0 +1,33 @@
# c风格字符串
`#include <cstring>`
```cpp
strcpy(buf1, "hello"); // 用后面的字符串覆盖前面的字符串
strncpy(buf1, "hello", 5); // 增加指定长度
strcat(buf1, "hello"); // 连接字符串
strncat(buf1, "hello", 5);
strcmp(buf1, "hello"); // 比较字符串,相等返回0
strlen(buf1); // 返回长度,不包括'\0'
strstr(buf1, "hello"); // 返回第一次出现子串的指针
strtok(buf1, " "); // 分割字符串,返回分割过的字符串
memset(buf1, 0, sizeof(buf1));//覆写内存块
memcpy(buf1, "hello", 5); //复制内存块
memmove(buf1 + 1, buf1, 4); //移动5个字节到前一个位置
```
## 两种转换
```cpp
string str1;
const char* str2 = str1.c_str();
const char* str3;
string str4(str3);
```

55
c++/universal/class.md Normal file
View File

@ -0,0 +1,55 @@
# 对象和类
## 访问控制
```cpp
class demo {
public: // 公有接口
private: // 私有成员
protected: // 保护
};
```
## 作用域运算符(::)
可用于在类体外指出函数所属的类(命名空间)
## 成员函数的参数名不可与类成员相同
## 类的六大特殊成员函数(未定义时编译器提供默认版本)
```cpp
demo::demo(); // 默认构造函数
demo::~demo(); // 默认析构函数
demo::demo(const demo&); // 复制构造函数
demo& demo::operator = (const demo&); // 赋值构造函数
demo::demo(demo&&); // 移动复制构造函数
demo& demo::operator = (demo&&); // 移动赋值构造函数
```
## const 成员函数 适合的成员函数要尽可能用,以帮助规避错误
`void show() const;` 声明
`void demo::show() const;` 定义
表明函数不会修改调用对象
## this指针
成员函数引用整个调用对象,可以使用 *this
## 作用域为类的常量(无法用const)
因为声明类只是描述了对象的形式,没有创建对象
+ 在类中声明一个枚举
```cpp
class const_demo {
private:
enum {Pi = 3.1415);
double s = 2*Pi;
};
```
+ 使用关键字 static
与其他静态常量存储在一起
` class demo {static const int Months=12};`
## 作用域内枚举
`enum class egg {small, large};`
使用后需要通过枚举名限定枚举量
`egg demo1 = egg::large;`
并且关闭了隐式转换的特性
explicit 禁止单个参数构造函数导致的自动类型转换

View File

@ -102,5 +102,4 @@ void stream_fio() {
ios::end
*/
}

View File

@ -0,0 +1,39 @@
# 存储说明符
+ static
+ extern
+ mutable
+ thread_local
# cv 说明符
+ const
+ volatile
## static
用在整个文件的声明中,表示内部连接性
局部声明中,代表存储持续性为静态
可将函数限制为内部连接性
`static void show();`
## extern
引用声明
声明引用在其他地方定义的变量
## mutable
即使结构(类)被声明为const,也可以被修改的成员函数
```cpp
struct people {
int scora;
mutable int accesses;
};
const people demo;
demo.accesses = 0;
```
## const
const 全局变量的连接性为内部(默认外部)
就像使用了static
如果希望连接性为外部则可以用extern覆盖
## volatile 强制读内存

43
c++/universal/template.md Normal file
View File

@ -0,0 +1,43 @@
# 模板
## 函数模板
### 基本格式
```cpp
template <typename T>
void swap(T &a, T &b) {
T temp;
temp = b;
b = a;
a = temp;
}
```
__函数模板必须放在头文件里因为它不是函数实体只能算编译指令__
### 模板的几个术语
+ **隐式实例化**
```cpp
int a=0, b=3;
swap<int>(a, b);
```
+ **显式实例化**
```cpp
template void swap<int>(int&, int&); // 使用模板生成int类型的函数定义
```
+ **显式具体化**
```cpp
template <> void swap<int>(int&, int&);
```
__这个可以放到其他文件里因为是有实体的__
### 类型推导
+ decltype()
```cpp
int a;
decltype(a) var;
```
## 类模板
+ 同样没有实体,包括类成员方法等都要写成模板的格式

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 414 KiB

View File

Before

Width:  |  Height:  |  Size: 405 KiB

After

Width:  |  Height:  |  Size: 405 KiB

View File

Before

Width:  |  Height:  |  Size: 397 KiB

After

Width:  |  Height:  |  Size: 397 KiB

View File

Before

Width:  |  Height:  |  Size: 478 KiB

After

Width:  |  Height:  |  Size: 478 KiB

View File

@ -1,2 +0,0 @@
nohup 命令挂机(退出登陆后依然执行)
nohup [command] &

View File

@ -1,39 +0,0 @@
`screen` 是一个功能强大的命令行工具,主要用于 Unix 和类 Unix 操作系统中,它允许用户开启多个独立的会话(称为"窗口"),在这些会话之间可以自由切换而不会中断已经运行的程序。以下是 `screen` 的一些主要功能和使用方法:
### 主要功能:
1. **多会话管理**:可以同时运行多个独立的 shell 会话。
2. **会话分离与重连**:可以从一个会话中分离出来,稍后再重新连接到该会话。
3. **窗口分割**:在一个 screen 会话中,可以水平或垂直分割窗口,以同时查看和操作多个任务。
4. **滚动记录**:可以查看会话的滚动记录,即使之前的输出已经滚出屏幕。
5. **复制和粘贴**:在 screen 会话中,可以使用快捷键复制文本并粘贴到其他位置。
6. **会话锁定**:可以锁定当前会话,防止他人查看或操作。
7. **自动保存会话**在网络断开或其他异常情况下screen 可以自动保存当前会话状态。
### 基本使用方法:
1. **启动一个新的 screen 会话**
```bash
screen
```
2. **列出当前的 screen 会话**
```bash
screen -ls
```
3. **重新连接到一个已存在的会话**
```bash
screen -r [会话ID或名称]
```
4. **分离当前会话**
在 screen 会话中按 `Ctrl-a` 然后按 `d`。
5. **在会话中创建新窗口**
在 screen 会话中按 `Ctrl-a` 然后按 `c`。
6. **在窗口之间切换**
在 screen 会话中按 `Ctrl-a` 然后按 `n`(下一个窗口)或 `Ctrl-a` 然后按 `p`(上一个窗口)。
7. **分割窗口**
- 水平分割:在 screen 会话中按 `Ctrl-a` 然后按 `"`(双引号键)。
- 垂直分割:在 screen 会话中按 `Ctrl-a` 然后按 `S`。
8. **调整分割窗口的大小**
- 增加/减少水平大小:在 screen 会话中按 `Ctrl-a` 然后按方向键。
- 增加/减少垂直大小:在 screen 会话中按 `Ctrl-a` 然后按 `Shift` 加上方向键。
9. **退出 screen 会话**
- 关闭当前窗口:在 screen 会话中按 `Ctrl-a` 然后按 `k`。
- 退出所有窗口并结束会话:在 screen 会话中按 `Ctrl-a` 然后按 `\`。
10. **锁定当前会话**
在 screen 会话中按 `Ctrl-a` 然后按 `x`。

View File

@ -1,4 +0,0 @@
#3 smartctl
查看硬盘状态参数
-a 全部参数
-H 是否正常

View File

@ -1,14 +0,0 @@
#5 ulimit
查看和修改进程运行资源限制
-H/S # 设置/显示 软/硬 限制
-a # 显示所有
-t # cpu time
-f # file size
-s # stack size
-c # core file size
-m # memory size
-l # lock memory size
-p # user processes
-n # open file
#ulimit -Ht 3600

View File

@ -1,37 +0,0 @@
Ubuntu 20.04.6 LTS \n \l
@@@@@@@@@@@@@@@@@ @@@ @@@@ @@ @@ @@
@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@ @@ @@ @@
@@@@ @@@ @@@ @@ @@ @@
@@@ @@@ @@ @@@@@@@@@@@@ @@ @@
@@@ @@@ @@@@@@@@@@@@@@@@@@@@@@@ @@ @@ @@ @@@@
@@@ @@ @@ @@ @@ @@ @@ @@ @@@@
@@@@ @@ @@ @@@@ @@@@ @@@ @@ @@
@@@@ @@ @@@@@@@@@@@@@@@@ @@@@ @@ @@@ @@ @@@
@@@@ @@@@ @@ @@ @@ @@@ @@ @@ @@@@ @@ @@
@@@ @@@@@ @@ @@ @@ @@@@ @@ @@ @@ @@
@@@ @@@@@@@@@@@@@@@@ @@ @@ @@ @@@
@@@ @@ @@ @@ @@ @@ @@ @@@
@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@ @ @@ @@ @@@ @@@@@
@@@ @@ @@@ @@ @@@ @@@@@@@@
@@ @@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@ aa
@@@ @@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@ @@@
@@ @@ @@@ @@@
@ @@@@@@@@@@@@@@@@@ @@ @@ @@ @@@ @@@
@@@@@@@@@@@@@@@@ @@@@ @@ @@ @@ @@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@
@@@ @@@ @@@@@@@@@ @@ @@@@@@@@@@@@@@@@@@@@@ @@@@ @@ @@@
@@ @@@@@@@@@@@ @@@ @@ @@ @@ @@@ @@@ @@ @@@ @@@ @@ @@@
@@ @@ @@ @@@ @@ @@ @@ @@@ @@ @@ @@@ @@@ @@@
@@ @@ @@ @@@ @@ @@ @@ @@ @@ @@ @@ @@ @@@ @@@@@@@@@@@@@@@@
@@ @@@@@@@@ @@ @@@ @@@@ @@ @ @@ @@ @@ @@@ @@@
@@ @@ @@@ @@ @@ @@ @@ @@ @@@ @@@
@@ @@@ @@ @@ @ @@ @@ @@ @@@ @@@
@@ @@ @@@ @@@ @@@ @@ @@ @@ @@@ @@@ @v
@@@@ @@@ @@@@@@@@@@@@ @@@@ @@@@@@@@@@@@@@@@@@@@@@@@@o

143
python/basics/demo.py Normal file
View File

@ -0,0 +1,143 @@
a1 = int(input("input:")) # input
print('%8d'%a1, '\n') # print
# print(objects, sep=' ', wnd='\n')
# 数据类型
x1 = 123
x2 = 123.123
x3 = True
x4 = "True"
print(x1, " ", type(x1))
print(x2, " ", type(x2))
print(x3, " ", type(x3))
print(x4, " ", type(x4))
print()
# 运算符
"""
1. **
2. * / % //
3. + -
4. <= < > >=
5. <> == !=
6. = %= /= //= -= += *= **=
7. not or and
"""
# 条件判断
if (x1==a1) and (x3==True):
print("OK!!!")
elif x3==False:
print("x3==False")
else:
print("x1:", x1)
print("a1:", a1)
print()
# 循环控制
for i in range(10): # 逐一访问序列中的元素
while i>=9 and i<13: # 通过条件控制
print(i)
i+=1
continue
break
# range() 函数 创建一个整数列表
"""
# 基本格式
range(start, stop,[step])
# 开始 结束 步长
range(5, 1, -1) # 可做到倒序输出
"""
# 字符串
s = str("Hello world")
print(s[3])
print(s[-3])
print(s[0:3]) # 字符串切片
print(s[3:])
print(s[:5])
print(s[:-5])
print(s[::-1]) # 倒序
len(s) # 计算长度
# 字符串查询
s.find('w')
s.count('l')
s.replace('H','h') # H变成h
s.casefold() # 大写转小写
s.upper() # 小写转大写
s.swapcase() # 转换大小写
eval('12+3') # 计算值 返回15
# 列表
li1 = [] # 创建空列表
li2 = list()
li3 = list(s) # 转换字符串成列表
li3.index('H') # 返回对应值的下标 反查
li4 = s.split(' ') # 通过空格分割字符串成列表
# li1[start:end:step]
for i,t in enumerate(li3): # 同时输出索引和值(列表本身也可以直接作为循环的序列)
print(i,t)
# 列表的更新与排序
li1.append([26,71]) # [26,71]作为一个元素追加到末尾
li1.extend([26,71]) # 将[26,71]每一项合并到末尾
li1.insert(1,520) # 将520插入位置1
li1[0] = 1314 # so easy
li1.remove(3) # 删除指定位置元素
li1.pop() # 默认删除-1位置的元素
li1.sort() # 对列表本身排序
li1.sort(reverse=True) # 对列表本身排序(倒序)
li2 = sorted.(li1) # 返回一个排序完的列表
# 元组tuple 元素不可修改的列表
t1 = ()
t1 = tuple(li1)
# 集合 set
set1 = {4,3,2,1}
set2 = set(li1)
set3 = set1 & set2 # 交集
set3 = set1 | set2 # 并集
set3 = set1 - set2 # 差集
set3.add(123) # 添加
set3.remove(123) # 删除
sum(set3) # 求总个数
# 字典 dict
dict1 = {'你好':'Hello'}
dict2 = zip(li1,li2) # 通过两个列表创建字典
del dict1['你好'] # 删除元素
dict1['再见'] = 'bey' # 存在更新,不存在添加
dict1.setdefault('','OK') # 存在不修改,不存在添加
s = dict1.get('','NO') # 不存在追加,存在返回原值不修改
for i,t in dict1.items(): # 遍历所有键值对
print(i,t)
for i in dict1.keys(): # 遍历所有键
print(i)
for i in dict1.values(): # 遍历所有值
print(i)
# 函数
def jc(n):
ans = 1;
for i in range(n):
ans *= i
return ans

9
python/modular/math.py Normal file
View File

@ -0,0 +1,9 @@
from math import *
n=(int)input()
ceil(n/24) # 上取整
round() # 四舍五入
abs() # 绝对值
max() # 最大值
min() # 最小值
pow(2,2) # 乘方

10
python/modular/random.py Normal file
View File

@ -0,0 +1,10 @@
from random import *
random() [0,1) # float
unifom(2.6, 7.1) [2.6,7.1] # float
randint(1, 10) [1,10] # int
randrange(1, 10) [1,10) # int
randrange(1, 10, 2) [1,10) # int %2==1
choice(list) # from list rand
choice(list, 2) # from list two

View File

@ -14,9 +14,13 @@ git init #创建仓库
--bare <code.git> #没有工作树的选项(多用于git服务器)
git add 文件 #将文件放到暂存区
* #所有 新建的,删除的,修改的
. #新建的,修改的
-u #删除的,修改的
-n 演习
* 所有 新建的,删除的,修改的
. 新建的,修改的
-u 更新已追踪
-f 允许添加忽略的文件
-A, --all 添加所有已跟踪和未跟踪
git commit #将暂存区修改合成一个提交
-m "填写概要"
@ -39,12 +43,16 @@ git diff #比对差异 与暂存区差异
git reflog #查询历史操作
git branch #显示所有分支
git branch #显示本地分支
xxx #创建名为 xxx 的分支
-a #查看当前工作分支相关信息
-r #列出远端仓库的所有分支
-a #查看全部分支
-r #列出远端分支
-d/D #删除分支 大写强制
-m/M #修改主分支 大写强制
-u <remote>/<branch> #设置追踪关系
-vv #查看每个分支的最后提交信息和跟踪关系
--merged #列出所有已合并到当前分支的分支
--no-merged #未合并
git checkout #切换分支
xxx #切换到 xxx 分支
@ -52,10 +60,20 @@ git checkout #切换分支
[file] #未提交的文件撤销修改
[hash] #回退
git switch #切换分支
-c xxx #创建并切换到 xxx 分支
git merge #合并分支
xxx #将 xxx 分支合并到当前工作分支
--no-ff #在历史记录中记录合并
--no-ff #在历史记录中记录合并 (尽量加这个)
--squash #将分支合并为一个提交进行合并,简化历史
--abort #假如合并过程中出现冲突,可使用这个命令终止合并
-m <message> #提交信息
--edit #创建合并提交前,允许编辑提交信息
#
# 若产生冲突,解决冲突后,需进行以下操作
# git add
# git commit
git reset #回溯
--hard HEAD~1 #撤销最后一次commit 本地仓库 and 暂存区 and 工作树
@ -66,9 +84,11 @@ git revert #提交一个反commit用于撤销前面的commit
HEAD
[hash]
git rebase #变基
-i #压缩历史
xxx #尝试与xxx分支同步合并
git rebase #变基 将一系列提交从一个分支上移植到另一个分支上
<basebranch> #将当前分支更改应用到<basebranch>分支上
-i #压缩历史 交互式变基
# -i HEAD~N #回退N次提交
--onto <newbase> <branch> #将<branch>分支变基到<newbase>上
--abort #当冲突时撤销合并
--continue #继续合并
@ -79,7 +99,7 @@ git stash #保存工作区当前状态
list #查看存储状态
pop #将最新一次记录恢复并删除
apply #默认恢复最新记录
clear #清所有记录
clear #清所有记录
show #看当前与栈顶差异
save xxx #提交注释
@ -103,9 +123,13 @@ git push #推送到远程
git pull #拉取远端仓库 全部 = git fetch + git merge
origin xxx #直接覆盖当前工作树
--rebase # = git fetch + git rebase HEAD
--rebase #将本地分支的提交应用到拉取的提交之上,保持历史线性
--no-commit #拉取并合并代码,但不自动提交结果
--edit #创建合并提交前,允许编辑提交信息
git fetch #拉取到本地仓库中 不对工作树进行覆盖
--all #获取所有远端仓库更新
--prune #拉取更新时,清理已删除的分支
git tag #查看所有标签
-d #删除标签

67
tool/makedown.md Normal file
View File

@ -0,0 +1,67 @@
大标题
======
中标题
------
# 一级标题
###### 六级标题
## 换行
+ 行末</br>
+ 两个空行
+ 行末两个空格
## 强调
+ *斜体*
+ **粗体**
+ ***粗斜体***
## 代码行
```cpp
#include<iostream>
int main() {
std::cout << "Hello makedown \n";
}
```
## 表格
|---|表头|表头|
|---|----|----|
| x | XX | XX |
| x | XX | XX |
+ -: 右对齐
+ :- 左对齐
+ :-: 居中
## 图片
+ ![图片名](图片地址)
## 链接
+ [链接名](链接地址)
## 其他
+ ~~删除线~~
+ <u>下划线</u>
+ [^READ]:脚注
## 列表
* 项目
+ 项目
- 项目
## 区块
>
> >
> > >

20
tool/nmap Normal file
View File

@ -0,0 +1,20 @@
# 一般探测步骤
# 1.主机发现
# 2.端口扫描
nmap -p- [目标] # 扫描全部TCP端口
nmap -p [端口] # 扫描指定TCP端口
nmap -sT # 使用TCP扫描 , 完成握手流程
nmap -sU # 使用UDP扫描
nmap -sS # 不完成整个握手过程
nmap -sUV # UDP + 版本探测 确认目标主机状态
nmap -sUV --top-ports 100 # 扫描常用的100端口
# UDP 由于探测不稳定性高,采用多次探测,因此速度慢
nmap -sn [目标] # ping 可用'-' 进行范围探测,内网ARP,外网ICMP包(会被windows server拦截)
nmap -sn 192.168.0.1-100
nmap -Pn [目标] # 可以绕过防火墙(慢) 不用Ping

View File

@ -4,6 +4,8 @@ g++ -o test test.o #链接
g++ -O1/-O2/-O3 // 优化选项
g++ -S -o - -fverbose-asm xxx.cpp > xxx.s // 输出带注释的汇编
#静态库制作:
g++ -c -o libtest.a {test.cpp 源代码文件清单}

View File

@ -1,12 +0,0 @@
INCLUDE = -I/home/e0x2d/include
main: file1.o file2.o
g++ -o $@ file1.o file2.o
file1.o: file1.cpp
g++ -c file1.o file1.cpp
file2.o: file2.cpp
g++ -c file2.o file2.cpp ${INCLUDE}
clean:
rm *.o demo

46
tool/program/makefile.md Normal file
View File

@ -0,0 +1,46 @@
# makefile
makefile 是一个通用的项目代码构建器
由规则 依赖 命令构成
规则:依赖
命令
+ -n 参数可以打印出make会执行的命令但不真正执行
# 注意: 命令前面必须要用Tab
# 伪目标
.PHONY:clean
# 自动变量
$@ 目标文件
$< 第一个依赖文件
$^ 全部的依赖文件
# 普通变量定义
OPTION = -O3 -Wall
# 变量使用
g++ $(OPTION) xxx
# 使用通配符
%.o: %.c
g++ $(OPTION) -c $< -o $@
```makefile
.PHONY:clean
INCLUDE = -I/home/e0x2d/include
main: file1.o file2.o
g++ -o $@ file1.o file2.o
file1.o: file1.cpp
g++ -c file1.o file1.cpp
file2.o: file2.cpp
g++ -c file2.o file2.cpp ${INCLUDE}
clean:
rm *.o demo
```

11
tool/program/objdump.txt Normal file
View File

@ -0,0 +1,11 @@
objdump
-f 显示文件头
-h 显示段(section)信息
-d 反汇编可执行段
-D 反汇编所有
-t 显示符号表
-T 动态符号表
-r 重定位
-R 动态重定位
-S 源码和汇编混合
-i 显示可用的架构,和目标结构

44
tool/program/readelf.md Normal file
View File

@ -0,0 +1,44 @@
# 在 Linux 系统中用于显示 ELF 格式文件信息的命令行工具
+ -a, --all
显示所有可用的信息。
+ -h, --file-header
显示 ELF 文件头信息。
+ -l, --program-headers
显示程序头表。
+ -S, --section-headers
显示节头表。
+ -g, --section-groups
显示节组。
+ -t, --section-details
显示节的详细信息。
+ -e, --headers
等同于 -h -l -S。
+ -s, --syms
显示符号表。
+ --dyn-syms
显示动态符号表。
+ -N, --dynamic
显示动态段。
+ -u, --unwind
显示 unwind 信息。
+ -I, --histogram
显示桶的直方图。
+ -x, --hex-dump=<section>
以十六进制形式转储指定节的内容。
+ -d, --use-dynamic
使用动态符号表代替静态符号表。
+ -r, --relocs
显示重定位入口。
+ -i, --notes
显示.note 节。
+ -A, --arch-specific
显示架构特定的信息。
+ -D, --dynamic-symbols
显示动态符号表。
+ -W, --wide
允许输出超过 80 个字符宽。
+ -H, --help
显示帮助信息。
+ -V, --version
显示版本信息。

5
tool/program/regexr.md Normal file
View File

@ -0,0 +1,5 @@
# 正则表达式
## 学习工具
+ https://regexr.com 查询网站
+ regex-vis.com 可视化表达式

View File

@ -1,36 +1,42 @@
SSH免密登录是一种使用SSH协议进行身份验证的方法它允许用户在不输入密码的情况下登录远程服务器。以下是实现SSH免密登录的基本步骤
# ssh 隧道转发
> 本地转发
+ 本地端口转发到远端服务器
+ ssh -L local_port:remote_host:remote_port user@ssh_server
> 远程转发
+ 远程转发到本地
+ ssh -R remote_host:local_host:local_port user@ssh_server
SSH免密登录是一种使用SSH协议进行身份验证的方法它允许用户在不输入密码的情况下登录远程服务器。以下是实现SSH免密登录的基本步骤
1. **生成密钥对**
- 在本地机器上打开终端或命令提示符。
- 使用`ssh-keygen`命令生成一对公钥和私钥。例如:
```bash
ssh-keygen -t rsa -b 4096
```
2. **复制公钥到远程服务器**
- 使用`ssh-copy-id`命令将公钥复制到远程服务器。例如:
```bash
ssh-copy-id user@remote_host
```
- 这将自动将你的公钥添加到远程服务器的`~/.ssh/authorized_keys`文件中。
3. **配置SSH客户端**
- 确保你的SSH客户端配置文件`~/.ssh/config`正确设置,以便使用私钥进行身份验证。例如:
4. **禁用密码登录**:
- /etc/ssh/sshd_config
- 设置PasswordAuthentication no
5. **测试免密登录**
- 尝试使用SSH连接到远程服务器如果一切设置正确你将能够无需输入密码直接登录。
6. **注意事项**
- 确保远程服务器的SSH服务配置允许密钥认证。通常在`/etc/ssh/sshd_config`文件中设置。
- 确保本地和远程的SSH配置文件没有错误并且权限设置正确。
7. **安全性**
- 使用强密码短语保护你的私钥文件。
- 定期更换密钥对以提高安全性。
以上步骤应该可以帮助你设置SSH免密登录。如果你遇到任何问题可以查看SSH的日志文件或使用`-v`参数进行调试,例如:
```bash
以上步骤应该可以帮助你设置SSH免密登录。如果你遇到任何问题可以查看SSH的日志文件或使用`-v`参数进行调试,例如:
ssh -v user@remote_host
```
这将提供详细的调试信息,帮助你诊断问题。
# ssh: config 文件
Host iaalai
HostName api.iaalai.cn #连接地址
User e0x1a #连接用户名
Port 20022 #连接端口
IdentityFile ~/.ssh/id_rsa #密钥地址
IdentitiesOnly yes #仅使用密钥
ServerAliveInterval 60 #每60s发一个空包保持连接
ServerAliveCountMax 3 #3次未响应断开

View File

@ -37,9 +37,3 @@ augroup numbertoggle 智能切换绝对行号和相对行号
autocmd BufEnter,FocusGained,InsertLeave,WinEnter * if &nu && mode() != "i" | set rnu | endif
autocmd BufLeave,FocusLost,InsertEnter,WinLeave * if &nu | set nornu | endif
augroup END
" vim笔记
" 使用 q[Key] 开始录制宏,再次点击q结束录制
" @[Key] 调用宏
"
" # 键向上查找当前单词

9
tool/vim/ShortcutKeys.md Normal file
View File

@ -0,0 +1,9 @@
# 小技巧
使用 q[Key] 开始录制宏,再次点击q结束录制
@[Key] 调用宏
# 快捷键
## ]f
在文件中若出现文件名,指针放在上面使用这个快捷键可直接打开

5
tool/web/game Normal file
View File

@ -0,0 +1,5 @@
indienova.com # 冰与火之舞
zh.minecraft.wiki
https://slowroads.io/
https://www.geo-fs.com/
yorg.io

17
tool/web/live Normal file
View File

@ -0,0 +1,17 @@
中国裁判文书网(https://wenshu.court.gov.cn/)
国家企业信用信息公示系统(https://gs.gsxt.gov.cn/index.html)
国家社会保险服务平台(https://si.12333.gov.cn/)
天地图(https://www.tianditu.gov.cn/)
国家统计局(https://www.stats.gov.cn/)
中国商标网(https://sbj.cnipa.gov.cn/sbj/index.html)
国家法律法规数据库(https://flk.npc.gov.cn/)
中国专利公布公告网(http://epub.cnipa.gov.cn/)
国家标准全文公开系统(https://openstd.samr.gov.cn/bzgk/gb/)
国家药品监督管理局(https://www.nmpa.gov.cn/datasearch/home-index.html#category=yp)
食品安全抽检公布结果查询系统(https://spcjsac.gsxt.gov.cn/)
发票查验平台(https://inv-veri.chinatax.gov.cn/?p=51,42&a=cjfb)
工信部申诉受理中心(https://ythzxfw.miit.gov.cn/index)
合同示范文本库(https://htsfwb.samr.gov.cn/)
中国法律服务网(https://www.12348.gov.cn/#/homepage)
中国庭审公开网(https://tingshen.court.gov.cn/)
中国关键词(http://keywords.china.org.cn/index.htm)

4
tool/web/program Normal file
View File

@ -0,0 +1,4 @@
https://mirrors.tuna.tsinghua.edu.cn/ # 清华开源站
https://linux.vbird.org/ # 鸟哥linux
https://www.52hb.com/ # 吾爱

6
tool/web/study Normal file
View File

@ -0,0 +1,6 @@
国家智慧教育公共服务平台(https://gjzwfw.www.gov.cn/)
终身教育平台(https://le.ouchn.cn/home)
国家数字图书馆(https://www.nlc.cn/web/index.shtml)
国家哲学社会科学文献(https://www.ncpssd.org/)
国家高等教育智慧教育平台(https://www.chinaooc.com.cn/)
职业教育专业教学资源库(https://zyk.icve.com.cn/)

5
tool/web/tool Normal file
View File

@ -0,0 +1,5 @@
kimi.moonshot.cn # kimi
www.tbtool.cn # 图吧
https://www.intel.cn/content/www/cn/zh/ark.html # intel CPU参数查询
https://cn.aliyun.com/ # 阿里云
https://next.itellyou.cn/ # 镜像站