$$$$ 命令选项查看方式
1.内建命令(help)
格式: help + 内建命令
#### help 命令 // 命令使用说明

2.外部命令(–help)
一般是 Linux 命令自带的帮助信息,并不是所有命令都自带这个选项。
如我们想查看命令 ls 的用法:ls --help

内建命令要比系统论命令有比较高的执行效率。外部命令执行时往往需要fork出(产生出)一个子进程,而内建命令一般不用。外部命令是在bash之外额外安装的,通常放在/bin,/usr/bin,/sbin,/usr/sbin…等等。可通过“echo $PATH”命令查看外部命令的存储路径,比如:ls、vi等。
————————————————
版权声明:本文为CSDN博主「打酱油的;」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_46098612/article/details/123187157

这是为什么echo应该内置shell 的真正原因:
假设您在中有密码$PASSWORD。您如何将其写入文件./password?自然,大多数程序员都会写:
echo "$PASSWORD" >./password
但是,如果echo不是内置的Shell,则密码将通过ps信息泄露给所有用户。
当然,如果您想对此有所了解,可以找到一种无需使用即可存储密码的方法echo,也许可以利用其他一些Shell功能:
cat >./password <<EOF
${PASSWORD}
EOF
但是,具有echo内置功能是一个重要的安全带,因为将密码保存到文件的最明显的方法也应该起作用。
https://qastack.cn/unix/1355/why-is-echo-a-shell-built-in-command

# mkdir 目录名 //创建目录(linux)/文件夹(win)
# mkdir -p d1/d2/d3/... //创建一串路径/目录; 递归创建多个目录

# pwd //显式当前目录的绝对路径

# touch 文件名.后缀 //创建普通文件

//#命令 -[命令选项] --后序学习"命令行参数和环境变量"
//command
//command not found :找不到命令

#echo "字符串" > 文件 //清空文件再写入,'w'

$ 文件 = 内容+属性
文件操作分为1.内容操作 2.属性操作

# ls -l(l:list) //以list的形式显式更多的属性

# ls -t //按时间先后排序
# ls -rt //按时间先后逆序排序

$ 以.开头的文件/目录是隐藏文件/目录

# ls -ul //以uid形式显式属性

# . //当前路径
# .. //上级路径

# C:\Users\26390\Desktop // windows下的路径, (反斜杠) \ : 路径分割符
# /root/test // linux下的路径, (斜杠) / : 路径分隔符

# ls -ld / //只显示路径,不显示内容
$ / 为linux下的根,linux下为目录为蓝色
$ windows下文件夹内可以有新的文件夹,linux下目录内可以有新的目录 -- 所以linux的根 / 和路径分隔符 / 不冲突
$ linux整体是一个多叉树的样子/结构

# ll -h // h: human_readable//人类可读的

$ windows通过路径来定位文件/文件夹,linux也是如此.
为什么呢? > 任何一个目录都可以有多个子目录,但一个子目录只有一个父目录 -->因此一条路径能唯一标识一目录/文件
$ 路径分为1.绝对路径 2.相对路径(相对是相对于当前路径,如果当前路径改变了,则相对路径也会发生改变 ->失效)

$ 绝对路径使用场景:准确但麻烦,一般是在某些配置环境中,进行对某种文件进行配置时采用!
$ 相对路径使用场景:用起来简单,是后序指令操作时,常用的路径定位方案!

# cd ~ //进入/home目录
$ 超级用户/管理员root的~独立位于/root
$ 普通用户的~都位于/home底下 -- ~称为普通用户的家目录
$ window也有家目录,位于C:\Users ,

# cd - //回到上一次访问的目录

热键:高频被使用的按键
# 快速双击tab键 -->命令的自动补齐:1.显式出匹配的所有命名 2.显示出匹配目录下的所有文件
# 不想进入目录又想查看其他目录有哪些文件 --> 无脑 tab../../../../

# tree [空] / [.] / [..] / [其他目录] //以树的形式把指定目录打印出来,不加命令选项默认是当前目录
$ -bash: tree: command not found 解决方法:root下# yum install -y tree //如果是Ubuntu,则是# apt-get install -y tree

$ 按键:ctrl+C //停止当前活动/打印/刷屏 /终止程序的运行/刷屏

# touch 文件 或 ../文件 //在当前目录创建一个普通文本文件 或在指定目录创建一个普通文本文件

# nano 文件 //使用nano编辑器u是什么意思打开文件

$ nano :nano是Unix/Linux下的一个文本编辑器
nano编辑器的快捷键使用
Ctrl+G 帮助
Ctrl+X 退出
Ctrl+O 保存
Ctrl+R 复制指定文件内容
Ctrl+W 查找
Ctrl+\ 替换
Ctrl+K 剪切
Ctrl+U 粘贴
Ctrl+J 调整段落
Ctrl+T 检查拼写
Ctrl+C 光标位置信息
Ctrl+Shift+_ 跳转到指定行
Alt+U 撤销
Alt+E 反撤销
Alt+A 从光标位置开始标记/选择
Alt+6 复制
Ctrl+3 & Shift+3 显示行号
//nano不能用数字小键盘,只能用数字横键盘

//cancel :取消

# cat 文件 // 打印/显式文件内容
$ 将[文件]或标准输入组合输出到标准输出。

# echo xx //显示一行文本,允许在标准输出上显示string , 将字符串打印到显示器

# gcc .c文件 //编译.c文件,得到a.out可执行文件 //可执行文件是绿色
# ./a.out //执行可执行文件,执行a.out文件 -- 可执行文件在linux下必须带./ ,后面学

$ 云服务器可以重启,但不要轻易关机

# stat 文件 //获取文件的所有属性
$ 任何文件都有三种时间:A.C.M.时间:1.Access(访问) 2.Modify(内容) 3.Change(属性)
$ ll显式的时间是M时间

# rmdir 目录 //删除目录,只能删除非空目录 -- 也没有支持递归删除的命令选项,所以目前没什么用
//rmdir:failed to remove :删除失败
$ 为什么要有 -- 如果有一个文件和目录同名,想删目录可以用rmdir 或 rm -r 目录, 想删文件用rm(默认删的就是文件) --这样就区分开来

# rm 指定目录/指定文件 //删除文件或目录 -- 什么都能删,只要权限够
# rm -r 指定目录 //递归删除目录内的所有文件/目录
# rm -rf 指定目录 //强制递归删除目录内的所有文件/目录 -- 不提示/不通知/不需要确认 直接删完

$ 普通用户只能在 /home/自己/... 内创建文件 ,root在哪里都可以创建

//3

//判断绝对路径 1.绝对路径是以/开始的 2.绝对路径放在任何目录下都与其他路径无关

$ 输入框为空时按一下table可以显式当前linux系统有多少条指令 -- 阿里云轻量应用级有1265条左右

//删除
# rm -r 目录 //通过rm删除目录,递归删除目录 -- 因为目录本身就是递归定义的

# sudo touch 文件 // 以root身份创建文件

# rm 文件 //只能删除普通文件 -- 默认只能删除普通文件

# yum install -y man-pages //安装man手册
# man [号] xx //搜索[几号]man手册并进入,没有号码则默认搜索全部
# man man //打开man手册首页

如果man2,3查不到,安装 yum install -y man-pages.noarch //先安装再更新 -- 原来是安装错了

//man 2 一般是系统调用
//man 3 一般是C库

$$ man命令选项
{
# -k 或 --apropos:用于搜索手册页面的简要描述。例如,man -k keyword会搜索包含关键字的手册页面的简要描述。
//可以搜索包含关键字的句子 所在的手册页
# -f 或 --whatis:用于查找手册页面的简要描述,类似于-k选项。
//只搜索目录,和直接man搜索一样,显示所在的手册页
# -p 或 --pager:指定用于查看手册页面的分页器(pager),默认情况下使用less。
//man -p less ls
//就是选择什么文档查看器来看文档
# -S 或 --sections:指定要查看的手册部分。默认情况下,man会搜索所有部分,但你可以使用此选项来指定特定部分。
//就是man 3 printf 的简写

}

# sudo 命令 //命令提权

//拷贝
# cp 普通文件 目录 // 拷贝普通文件到目录中
# cp -r 目录 目录 // 拷贝目录到目录中,必须带-r,递归拷贝

$ 命令选项可以放中间也可以放在最后 // 最好保持放中间,有些系统不支持,如mac

//剪切
# mv 目录/文件 目录 //移动目录/文件,不需要带递归-r命令选项 ,后面一项一定是目录
# mv 目录/文件 .. //移动文件/目录到上级目录
# mv 目录/文件 . //移动文件/目录到当前目录

//文件重命名
# mv 旧文件名 新文件名 //重命名 -- 后面一项一定时文件名

//文件剪切+重命名
# mv 旧文件名 路径/new_filename(带目录的新文件名) //如果第二项是是目录且带着一个没有重复的文件名,则是移动+重命名

//目录重命名
# mv 目录 新目录名(不能和所在路径有重复) //当前目录下重命名

//目录剪切+重命名
# mv 目录 带路径的新目录名(不能和所在路径有重复) //

//linux下一起皆文件,键盘,显示器...可以读,可以写都是文件

# cat 文件 //打印文件内容到显示器

# echo 文本内容 // 输出到控制台 - 文本内容目前最好带上""

# echo 文本内容 > 文件 // 输出 文本内容 重定向 到文件 , '>'为输出重定向符号 -- 如果文件不存在,输出重定向>会创建一个新文件并写入
$ '>'输出重定向是一种覆盖式写入 ,清空文件再写入
$ '>>' 追加重定向:追加重定向是追加式写入,在原文件内容的末尾追加写入,给原文件新增内容
// 重定向 redirect

# wc 文件 //wc命令的功能为统计指定文件中的字节数、单词数、行数, 并将统计结果显示输出
-c, --bytes打印字节数
-m, --chars 打印字符数
-l, --lines 打印行数 //学
-L, --max-line-length 打印最长行的长度
-w, --words 打印单词数
//作用,可以统计总代码行数.
# wc -l * 统计当前项目下的所有代码行数

//示例
# who | wc -l //按行统计

$ '<' 输入重定向

$ cat默认是重键盘读取数据 -- 只输入cat就会进入键盘读取状态,打一个回显一个,直到ctrl+C
# cat < 文件 //读入重定向到文件,默认是键盘 -- 和# 【cat 文件】 不一样 , 【cat 文件】是命令获取文件

//cat用法:cat [选项] [文件]...
将[文件]或标准输入组合输出到标准输出。
-A, --show-all 等价于 -vET
-b, --number-nonblank 对非空输出行编号
-e 等价于 -vE
-E, --show-ends 在每行结束处显示 $
-n, --number 对输出的所有行编号 //学
-s, --squeeze-blank 不输出多行空行 //把连续的空行合并成一行
-t 与 -vT 等价
-T, --show-tabs 将跳格字符显示为 ^I
-u (被忽略)
-v, --show-nonprinting 使用 ^ 和 M- 引用,除了 LFD 和 TAB 之外
--help 显示此帮助信息并退出
--version 输出版本信息并退出
如果[文件]缺省,或者[文件]为 - ,则读取标准输入。

# more 文件 //按屏幕大小显式文件内容 -- 按回车翻页,并且只能向下翻页,按q推出

{
# less 文件 //按屏幕大小显式文件内容 -- 按上下键翻页,可以自由翻页,按q推出
//搜索 输入/搜索内容+回车 , 转到下一个搜索结果按n(next)
less 与more命令类似,但可以通过翻页键查看上下页的内容
-b<缓冲区大小> 设置缓冲区的大小
-e 当文件显示结束后,自动离开
-f 强迫打开特殊文件,例如外围设备代号、目录和二进制文件
-g 只标志最后搜索的关键词
-i 忽略搜索时的大小写
-m 显示类似more命令的百分比
-N 显示每行的行号
-o<文件名> 将less 输出的内容在指定文件中保存起来
-Q 不使用警告音
-s 显示连续空行为一行
-S 行过长时间将超出部分舍弃
-x<数字> 将“tab”键显示为规定的数字空格

命令内部操作按键功能如下:
b 向前翻一页
d 向后翻半页
h 显示帮助界面
Q 退出less 命令
u 向前滚动半页
y 向前滚动一行
空格键 滚动一页
回车键 滚动一行

1) 向前搜索
/ : 使用一个模式进行搜索,并定位到下一个匹配的文本
n : 向前查找下一个匹配的文本
N : 向后查找前一个匹配的文本

2) 向后搜索
? : 使用模式进行搜索,并定位到前一个匹配的文本
n : 向后查找下一个匹配的文本
N : 向前查找前一个匹配的文本

2 全屏导航
ctrl + F :向前移动一屏
ctrl + B :向后移动一屏
ctrl + D :向前移动半屏
ctrl + U :向后移动半屏

3 单行导航
j : 向前移动一行
k : 向后移动一行

4 其它导航
G : 移动到最后一行
g : 移动到第一行
q / ZZ : 退出 less 命令

5 编辑文件
v : 进入编辑模式,使用配置的编辑器编辑当前文件

6 标记导航
当使用 less 查看大文件时,可以在任何一个位置作标记,可以通过命令导航到标有特定标记的文本位置。
ma : 使用 a 标记文本的当前位置
'a : 导航到标记 a 处

7 浏览多个文件
方式一,传递多个参数给 less,就能浏览多个文件。
less file1 file2

方式二,正在浏览一个文件时,使用 :e 打开另一个文件。
less file1
:e file2

当打开多个文件时,使用如下命令在多个文件之间切换
:n - 浏览下一个文件
:p - 浏览前一个文件

}

# head 文件 //默认会把文件的前10行打印出来,不够10行有多少打多少
# head -n5 文件 //设置成只打印前5行
# head -5 文件 //一样,省略,设置成只打印前5行

# tail 文件 //
# tail -3 文件
# tail -n3 文件

# wc -l 文件 //统计文件有多少行

# cat 文件 | wc -l //cat的数据流入管道,wc统计管道数据的行数

$ '|' //管道 ,管道最核心的意义在于:可以级联多条命令,让命令和命令组合,来完成批量化文本处理任务,做数据的不断加工
//从左到右一次执行,结果由最后一条命令输出

//时间

# date //linux时间
# date +%Y-%m-%d_%H:%M:%S //格式化输出时间
# date +%s //输出时间戳 -- 格林尼治时间 --因时区问题,显式为8:00
# date +%Y-%m-%d_%H:%M:%S -d @时间戳 //将时间戳转为格式化输出

//
日历 calendar [ˈkælɪndər]
# cal //显式当前月份日历
# cal 2023(年份) //显式该年的所有月份
# cal -3 // 显式本月和前后月 //*只有命令选项只有-3

# sort 文件 //按行的ascii比较,默认是升序 -- 排序后打印
# sort -r 文件 //降序 r为reverse
# sort 文件 | uniq //排序后去重 -- 单纯去重没有用
//sort - uniq都不会修改源文件

//搜索三件套
# find 路径 -name 文件 //在路径底下搜索文件 -- 第一次搜索很慢,第二次会快,因为linux会把常用搜索缓存起来
要获取特定文件的路径
find ~ -name example.txt //范围尽可能小,使用~比较好

# which 指令 //搜索指令所在目录 //搜索可执行程序

# whereis 文档/程序/压缩包... //搜索各种

$ linux基本所有指令都在 /usr/bin下
$ linux指令是可执行程序(绿色),就是平时写的C语言代码编译好的可执行程序 --指令,程序,工具没本质区别

# alias 别名='命令+命令选项组合' //给命令+选项起别名
$ 为什么我们ls时有些文件会带颜色: 因为ls是'ls --color=auto的'别名

$$$$$ grep
{
//文本 行过滤工具
# grep '关键字' 文件 //过滤出文件中具有关键字的行 -- grep为文本行过滤工具

# >文件 //清空文件内容 --输出重定向,覆盖式,覆盖空进去,所以清空

# grep -v '关键字' 文件 //过滤掉文件中具有关键字的行 -- 不显示有关键字的行
// grep -ivn '关键字' 文件 //组合命令
//cat 文件|grep '关键字' 文件 //管道级联组合
注意:grep尽量带''或"",特别是有空格或其他符号

# grep -E 'proc1|command' //启用正则表达式查询 proc1或其他关键词.
// egrep == grep -E //是别名

# -c选项 //仅显示行号
# -n选项 //描述+行号
# -i选项 //ignore,忽略大小写
}

# top //任务管理器linux
//特殊:进入后台后就无法进到前台了

//zip打包 并压缩
# zip 打包的包名.zip 要打包的文件/目录 // 把文件打包 -- 只打包当前(1个/最外层)目录或文件
# zip -r 打包的包名.zip 要打包的文件/目录 // 递归打包文件/目录

//zip解包
# unzip 要解包的文件(xxx.zip)

# unzip 压缩文件 -d 路径/目录 //解压缩到指定目录 d:dir

# zip 文件.rar 文件 // 没问题 后缀名可以为7z,rar,zip,解压也可以,用unzip --- 猜测是压缩算法是zip,后缀格式兼容或无所谓

//zip安装
# yum install -y unzip zip //安装 zip和unzip,可以把zip和unzip分开写 -- 安装多个包时用空格分开

zip文件查看压缩包
{
zip -sf rumenz.zip

unzip -l rumenz.zip

zipinfo rumenz.zip

less rumenz.zip

vim rumenz.zip

}

# ls [命令选项] 目录/路径 //以列表形式显式该目录

# rm * -rf //把当前目录的所有文件删掉 -- 不带路径默认为当前目录 -- '*' ,linux通配符,代表所有文件
# rm *.后缀 -rf //把带有相同后缀的文件全部删除
$ 通配符:可以匹配上任意个数的任意字符

# tar -czf 档名(名.tgz) 文件 //c为create:创建一个新的归档文件,即打包; z为使用gzip压缩,即压缩; f:使用档名,即紧接档名(新名),不能再接命令选项 //一般建议把f放最后,档名一般为tgz后缀
# tar -xzf 压缩文件 //x(extract提取):解压指令(只需把czf的c换成x),准备解包; z:曾经压缩过,现在需要解压;f:文件名
$ tgz: t:tar gz:gzip//压缩:gzip压缩算法 //.tar.gz 的缩写 .tgz

# tar -ztvf 压缩文件 //查看压缩包内但不解压 //z为解压(解压一些头部信息)或者检查是否gzip , t--list为查看指令 v--verbose为列出更详细信息 f为归档文件名
# tar tvf 压缩文件 //目前和ztvf一样

//有的平台上命令选项可以不带'-'

# tar -xzf 压缩文件 -C 目录/路径 //解压到指令路径/目录 //-C和zip的-d含义一样 -- 默认都是解压到当前路径

$ linux支持多行输入 ,只要在结尾输入反斜杠\回车即到下一行 -- 不需要空格等,空格也算命令中

//热键:ctrl+C :终止在影响命令行输入的程序,回到命令行输出

# bc //linux中的计算器
# echo "1+2*3/2" | bc //管道组合运算 -- 结果为4

# uname -a //查看所有信息 // Linux iZ7xv3f3wlfxwevnefn5drZ 3.10.0-957.21.3.el7.x86_64 #1 SMP Tue Jun 18 16:35:19 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux
//linux版本 3.10.0; 发行版:el:centos 7; 架构:x64;

# uname -r //查看软硬件体系结构 //软件体系结构3.10.0-957.21.3. 硬件体系结构: el7.x86_64

# cat /etc/redhat-release //查看linux的商业化发行版 -- centos是redhat公司的一款免费系统

# exit //退出linux

$ ctrl+d //退出//通常代表着:『键盘输入结束(End Of File, EOF 或 End OfInput)』的意思;另外,他也可以用来取代exit

$ 在输入框按上或按下可以翻动历史命令

$ ctrl+r //搜索历史命令

# history //显式最近1000条命令
# history > 文件 //把命令保存到文件中
//配合!使用
# !history编号 //执行该编号的命令
# !! //执行上一次的命令

# reboot //重启linux
# shutdown [命令选项] //关机 -- 云服务器不关机,关机要去后台重启

// 命令输入的地方叫做: 命令行 / CLI/命令行界面

$ Shell的最简单定义:命令行解释器(command Interpreter)主要包含: -- shell的感性理解
.将使用者的命令翻译给核心(kernel)处理。同时,将核心的处理结果翻译给使用者
.保护操作系统 -- 防止用户执行非法指令
.执行命令会创建子进程进行执行
//我们平常的命令主要是通过shell来和linux内核交互,shell帮我们解释命令给kernel -- shell命令
//shell是一个程序/命令 :/usr/bin/bash ,即bash. 我们链接上服务器时会自动关联上shell程序 -- bash也是一个可执行程序,C语言写的
//shell是linux的外壳程序,是软件层,命令行

// shell是适配程序,将内核适配后提供给用户合适的接口 --
$ shell是所有外壳程序的统称,linux的内核程序是bash ,统称shell

//权限
$ 权限的概念:权限 = 人 + 属性
#

$ 权限是约束普通用户的,超级用户不受约束 ,想看就看,想改就改

$ linux的文件属性
- --- --- ---
- rwx rwx rwx

$ linux下文件类型不用后缀区分文件类型,而是用文件属性中的第一列的一个字符区分文件类型
// 文件类型:
// '-'是普通文件 ,包括文本文件,可执行文件,归档文件(压缩包)等
// 'd'是目录
---------------------
// 'b':块设备,block,如磁盘
// 'c':字符设备,如键盘,显示器
// 'p':管道文件,
// 's':网络socket文件
// 'l':链接文件,link

$ linux虽然不以后缀区分文件类型,但是可以给人看,
// a.我们可以使用后缀名
// b.我们把后缀当作文件名的一部分
$ linux不以后缀区分文件类型是linux操作系统的事,我们的程序可以使用后缀来识别文件
$ linux程序与后缀无关,改成什么名都能执行.但是linux程序不一定能识别后缀不符合的文件,因为linux程序也是人写的
//即:操作系统以文件类型区分,用户程序可以以后缀区分文件.互不影响

# whoami //查看我是谁
# who //查看在线用户
# w //详细信息
[chj@expiration1102 ~ 18:40:04]$ w
18:40:12 up 19 days, 19:45, 1 user, load average: 0.01, 0.04, 0.05
USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT
chj pts/0 14.150.227.120 18:40 4.00s 0.00s 0.00s w

//超级用户
# su 任何用户 //切换到任何用户,无需密码

//普通用户
# su // 切换到超级管理员.需要输入密码 //在同一个bash下进行身份切换
# su - //以root身份重新登录,
# su 同级用户 //切换到同级用户,需要输入密码
//su:switch user

$ ctrl+d是登出用户,用户可以su其他用户,套娃. 登出时按登入顺序依次退出 -- 栈结构

# sudo 命令 // 普通用户单条指令提权
//会有错误aaaa is not in the sudoers file. This incident will be reported.//以后解决

//角色划分

1.文件拥有者

2.文件所属组

3.文件的other(其他人) :如果不是拥有者或所属组,自动识别成other -- root也会被识别成other,但是不能影响root的霸权

文件信息示例:
: - rw- rw- r-- 1 chj chj 0 Sep 6 20:47 test.txt
:文件类型 拥有者权限 所属组权限 other权限 文件拥有者 文件所属组 文件大小 日期 文件名

文件权限: -- 文件自身具有权限属性
r -- 可读 -- 补充:可查看目录内文件
w -- 可写 -- 补充:目录内可新增、删除文件
x -- 可执行
- -- 该位置没有权限

$ 文件权限如果存在则显式对应位置的相应字符(rwx),没有则为'-'

$ 由于权限 = 人+属性,,要修改文件的权限,要么更改人,要么更改属性 -- 默认是文件的拥有者和root可以更改

//更改权限

//增加
# chmod u+r 文件 //Change Mode ,ch:change mod:mode //u代表拥有者user,+代表添加权限,r代表读权限;即给拥有者添加读权限
# chmod g+w 文件 //Change Mode ,ch:change mod:mode //g代表所属组group,+代表添加权限,w代表写权限;即给所属组添加写权限
# chmod o+x 文件 //Change Mode ,ch:change mod:mode //o代表其他人other,+代表添加权限,x代表写权限;即给其他人添加可执行权限

//移除
# chmod u+wx 文件 //u代表拥有者user,+代表添加权限,wx代表写和可执行权限;即给拥有者添加写和可执行权限
# chmod g+rx 文件 //g代表所属组group,+代表添加权限,rx代表读和可执行权限;即给所属组添加读和可执行权限
# chmod o+rw 文件 //o代表其他人other,+代表添加权限,rw代表读和写权限;即给其他人添加读和写权限

//权限顺序不影响,如 wrx,xrw,rxw...

//组合
# chmod o-rwx 文件 // 去掉o的rwx权限 '-'代表移除权限
# chmod u+x,g-w,o+w,u-x 文件 //组合增删权限,以逗号分隔

//所有+组合
# chmod a+x,a-w 文件 //给所有用户增加/删除权限 //a(all)代表所有用户

//默认,所有
# chmod +r 文件 //给所有用户ugo加上读权限 //

//二进制/八进制表示
$ 权限的每一个选项位,如果有对应权限则为1,如果没有则为0. 由此如果一文件拥有者权限为rw-,则二进制表示为110
$ 有三个用户组,每个用户组对应3个二进制位,这3个二进制位可以合并成一个八进制,即每3个二进制位为1个八进制,总共有9个二进制,则共有3个八进制位.
//设某文件权限为 110 110 100,则八进制为 664

$ 注意: 0开头代表是8进制数字

//八进制更改权限
# chmod 000 文件 //移除所有权限
# chmod 664 文件 //等价与110 110 100.//等价于chmod u+rw,g+rw,o+r 文件
# chmod 777 文件 //添加所有权限

$ sudo 命令 //命令提权,是以root身份执行,并不单纯是用户具有root权限 -- 需要在linux中把该用户添加到信任列表才能sudo

//更改所有者“chown是change owner的缩写//所有者
//更改所有组 chgrp是change group的缩写

$ 只有高级用户能强制给给低级用户文件,即root和能sudo用户

$ sudo输入密码后,短时间内再次使用sudo不需要密码 -- 方便人操作 --一般是15分钟以内

# sudo chown 用户 文件 //把文件所有者改为别的用户
# sudo chgrp 组 文件 //把文件的所有组改为别的组
# sudo chown 用户:组 文件 //同时修改用户和组

# chmod -R u+r 文件 //递归子目录修改权限

//file:查看是什么类型文件
# file txt文件 //test.txt: ASCII text
# file 目录//test.txt: ASCII text
# file C可执行文件//a.out: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.32, BuildID[sha1]=8261fb1b71b64a95f1a5f4be1559f4da3b0e339e, not stripped
# file .c文件//test.c: C source, ASCII text
# file tgz归档文件 //test.tgz: gzip compressed data, from Unix, last modified: Thu Sep 7 09:52:44 2023
$ 命令选项
-c 详细显示指令执行过程,便于排错或分析程序执行的情形。
-z 尝试去解读压缩文件的内容。

//目录权限
//r:查看,
//w:创建,移动...更改文件
//x:进入目录
//没有权限:permission denied

//centos默认权限
$ 文本文件的默认权限是664 rw-rw-r-- //可查看,可修改,可执行
$ 目录文件的默认权限是775 rwxrwxr-x //可查看,可增/删文件,可进入目录

$ 不同操作系统默认权限可能不一样

$ linux 权限分为
1.起始权限 -- 系统设定的,文本文件起始权限是666(没有可执行x),目录是777(都有)
2.最终权限(系统角度)/默认权限(用户角度)

$ 权限掩码/umask:在起始权限中,去掉umask中出现的权限,不能影响其他权限的码 -- 用于系统更好的控制文件权限
// 掩码就是一串二进制数字,可以将源码与掩码经过按位运算或逻辑运算得出新的操作数

$ linux掩码有4位(八进制),最左边一位目前用不到,现在只使用后三位 -- 默认为0002 //最高位一般给系统标记位使用,1777,2664 3xxx ...
# umask 0002 // 修改掩码为0002 -- 掩码可以修改

最终权限 = 起始权限 & (~umask)

$ 异或 和 取反与 不等价 -- 容易出现相等的巧合
比如 3 ^ 4 = 7
二进制是 00000011 ^ 00000100 = 00000111
3 &~ 4 = 3
二进制是00000011 &(~ 00000100 )=00000011 &11111011=00000011=3

//粘滞位
//背景:linux中有共享目录,被所有普通用户共享,用来保存普通用户产生的临时数据
//linux下家目录只对自己开放,其他人无法访问(rwx --- ---/700) -- 由于不同用户之间需要交换数据,因此有了共享目录
$ 共享目录通常由root提供,任何人访问的身份都是other

$ 粘滞位的功能,限制目录内的文件只有文件拥有者和root可以删除 -- w目录有增/删文件功能,t是限制一部分

//一般情况,别人进不去我的家目录,别人删不掉,所以我的文件很安全.但是在共享目录下,如何防止被别人删除文件就很必要了

//粘滞位 -- 为了让大家共享文件,且不让其他人随便删除别人的文件 -- 提出了粘滞位

$ 粘滞位只能给目录添加 -- 一般对共享目录添加.
$ 且只加到other的x位上 -- 可执行权限x对目录来说没用
# sudo chmod +t 目录 // 给目录添加粘滞位,a+t,+t都一样

$ 增加粘滞位的目录内的文件只有文件拥有者和root可以删除/目录的所有者也可以删除

$ 目录的w权限还有删除文件的功能

$ 粘滞位一般都在rwx的基础上添加

ls/cd/pwd/whoami/touch/mkdir/rm/rmdir/bc/cat/less/more/nano/date/wc/grep/head/tail/zip/unzip/tar/clear/cal/man/echo/tree/find/which/whereis/file/
cp/mv/chmod/chown/chgrp/sort/uniq/gcc/su/sudo/top/stat/uname/alias/umask/adduser/passwd/userdel/history

"重定向>,>> " , "管道|" , " ~ , - " , "家目录" , "文件类型" , "目录权限" ,"umask" ,"粘滞位" ,"权限"

//

//yum -- 应用商店 -- 仓库

软件包名称: 主版本号.次版本号.源程序发行号-软件包的发行号.主机平台.cpu架构.
"x86_64" 后缀表示64位系统的安装包, "i686" 后缀表示32位系统安装包. 选择包时要和系统匹配.
"el7" 表示操作系统发行版的版本. "el7" 表示的是 centos7/redhat7. "el6" 表示 centos6/redhat6.
最后一列, base 表示的是 "软件源" 的名称, 类似于 "小米应用商店", "华为应用商店" 这样的概念.

# yum list //列出yum所有程序 -- 软件名-版本号-@提供者

# yum search 关键字 //匹配有关键字的程序 -- 不好用

# yum list | grep 关键字 //好用

$ 版本中带el就是centos ,el7就代表centos7
//x86:架构 x86_64:x86架构64位系统

$ ctrl+Z :终止程序 -- 有些程序ctrl+C终止不了

//安装
# yum install 程序名(严格匹配) //安装程序 ,需要确认安装
# yum install -y 程序 //直接安装到位,不需要确认

yum -y install gcc+ gcc-c++ //g++安装

//卸载
# yum remove 程序名 //卸载程序,需要确认卸载
# yum remove -y 程序名 //直接卸载

$ 程序sl:一个火车动画

# 软件仓库内内置了各个软件的下载地址/配置文件
//yum的配置文件 -- yum源

$ yum源位置 /etc/yum.repos.d/下

$ centos的基础yum源: CentOS-Base.repo
$ 还有 epel.repo

$ //前面带"$"符号的单词表示这个单词是宏,会被替换掉

//更新yum源
1.备份原来的yum源 CentOS-Base.repo
2.wget 新的yum源
3.mv 重命名成为 CentOS-Base.repo
4.yum clean all //清空缓存
5.yum makecache //生成新的缓存

//可能在扩展yum源中的软件安装
1.# sudo yum install -y epel-release //根据base_yum源去找到匹配的yum源
2.# sudo yum install -y

//复习->

//软件包和软件包管理器 -- 类似于App与应用商店
//软件包是已经由源代码编译好的可执行程序,包管理器能方便得获取到软件包

//5

//vim是vi的升级版本,vi有的vim都有,现在都使用vim

//集成开发环境/IDE :VS2019 //特点是功能齐全,把所有功能都集中在一起,一个软件能所有工作

//vim就是一个单纯的编辑器
//vim

$ vim是一款多模式的编辑器 -- 有各种模式 -- 常用就3-5种
1.命令模式(vim默认打开就是)
2.插入模式
3.低行模式
4.替换模式
5.视图模式
...

//vim命令
{

$ 任何模式按esc都能回到命令模式,命令模式能进入任何模式

$ 命令模式下按shift+:进入低行模式
// 低行模式中,w为write写入/保存,q为退出,组合命令wq为保存并推出 --- 如果文件被修改,则必须要w命令
// 低行模式,1.set nu为显示行号,nu为number 2.set nonu 为关闭行号
// 低行模式中 /关键字 为搜索 ,搜索模式中n向下匹配,shift向上匹配
// 低行模式中,!为强制,w!为强制保存 wq!为强制保存并退出
:x 保存并退出,同 :wq
:x! 强制保存并退出,同 :wq!
:
// 低行模式中,!空格+linux命令 为执行linux命令

// 低行模式中,vs什么都不加会打开多一份相同的文件,内容同步 -- 光标在哪里,则操作的就是谁
// 低行模式中,vs+文件名会打开多个文件多屏操作,如果文件不存在也能打开,不修改退出则不会生成新的文件,保存则会生成新的文件
//:vs为并列方式打开多个文件
//:sp为上下行方式分开多个文件
//ctrl+w+q 或:close 为关闭当前窗口..

Linux vim 文本替换 %s/原文/替换文本/g
{
语法:%s///g
ESC:%s/origanl/new/g --grammar:语法?

%s 表示替换文本。
origan 表示原文
new 表示新的内容
/g 表示全文替换,如果仅替换第一个则不需要/g

需要注意如果要替换的内容中包含特殊含义的自负,需要使用转义符转义

————————————————
版权声明:本文为CSDN博主「Drifting Kern」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_43740223/article/details/119925821
}

$ 命令模式下按i进入插入模式:光标不动,往光标前面插入
$ I 从目前光标所在行的第一个非空白字符处开始插入
$ 命令模式下按a进入插入模式:光标往后退一格,往光标前面插入
$ A 从目前光标所在行的最后一个字符处开始插入。
$ 命令模式下按o进入插入模式:往下插入一行并光标进入行首
$ 命令模式下按shift+o进入插入模式:往上插入一行并光标进入行首
$ 命令模式下按s进入插入模式:删出当前光标所在字符后光标不动,进入插入模式,往光标前面插入
$ 命令模式下shift+r 进入替换模式 ,输入会替换掉原有字符
$ 命令模式下按shift+s / cc清空当前行进入插入模式
$ 命令模式下按ZZ/shift+zz快速保存并退出
$ 命令模式下按Ctrl+Z 生成swap临时文件并退出
$ 命令模式下按.可重复上一次操作
$ 命令模式下按shift+q可以进入低行模式(更近的键盘操作,Qq退出)

【Ctrl + O】向后回退你的光标移动

【Ctrl + I 】向前追赶你的光标移动

fa → 到下一个为a的字符处,你也可以fs到下一个为s的字符。
ta → 到a前的第一个字符。a可以变成其它字符。
还有一个很有用的命令是 dt" → 删除所有的内容,直到遇到双引号—— "。 //或df
g_ → 到本行最后一个不是blank字符的位置。

$ 操作复制器:
qa #打开操作记录器,将后续动作放在记录器a中;(左下角会显示一个【记录中@a】提示符号)
q #关闭记录器; --->备注:此时仍处于normal模式
执行操作
n@a // 执行n次操作,不带则为1次

Vim生成递增递减的数字
ctrl+a #数字自加一次; --->备注:如果想生成间隔n个数跳跃递增,则先按数字,再按下ctrl+a;
ctrl+x 递减

$ 命令模式指令:
// yy 复制 , nyy复制光标以下n行
//yw 复制光标所在字符右边的单词
// p 粘贴 ,np粘贴n行,粘贴到下一行,粘贴当前光标所在的下一行,并且光标移动到一行 \ // 100p 粘贴100行 --
// P 往上/左粘贴
// u 撤销undo
// ctrl+r 对撤销进行撤销/撤销命令u所作的操作,反撤销,重做 -- redo
// dd行剪切,ndd往下剪切n行 // 如果只dd不粘贴,则是删除
// x 删除光标当前所在位置 ,nx 删除光标连续的n个单词
// shift+nx 往前删除
shift+d / D 删除光标及后面的.当前行

//dG 删除当前及以下所有行
//d$/D 删除从光标所在字符到行尾的数据
//d0 删除从光标所在字符到行首的数据

// 光标移动
h: 左, h在最左侧
ctrl+h:可以退行的左
j: 下, jump
k: 上, king
l: 右, l在最右侧

使用g-命令:这个命令可以将你当前的光标位置返回到修改历史中的前一个节点。输入`g-`后跟一个数字参数可以指定返回前几个节点的信息。
使用g;命令:这个命令将把你的光标位置移动到修改历史中的后一个节点。通过多次执行`g-`和`g;`命令可以实现向前和向后浏览修改历史。
gg=G命令: 格式对齐

vim 可视化选择
v 字符选择,会将光标经过的地方反白选择 -- 再按一次取消
V 行选择,会将光标经过的行反白选择
ctrl+ v 块选择 -- 绿色也会删掉
d 将反白的地方删除掉。(d)elete
D 将反白的地方经过的行都删除掉。(D)elete
y 将反白的地方复制。(y)ank
p 将刚刚复制的区块,在光标所在处贴上。(p)ut
u 将选中部分的字符全部改为小写
U 将选中部分的字符全部改为大写
> 将选中部分右移(缩进)一个 tab 键规定的长度(CentOS 6.x 中,一个tab键默认相当于 8 个空白字符的长度)
< 将选中部分左移一个 tab 键规定的长度(CentOS 6.x 中,一个tab键默认相当于 8 个空白字符的长度)

//linux批量化处理命令 -- 块模式
# ctrl+v+选择行+I,输入符号,esc // 批量化添加,即块添加,一般用于注释
# ctrl+v+选择块+d //块删除

$ vim标记cursor和取消
# shift+* //高亮所有标记的单词
# :noh //取消高亮

//vim在退出前,可以撤销和undo.保存也可以
//vim在退出后,之前的修改不能再撤销

## 快速定位
f<char> //f+字符==移动到该字符,shift是往前移动 -- 仅当前行
//shift+g移动到文本尾行
//gg 移动到文本首行
//n+shift+g 移动到第n行

//shift+$ 定位到句尾
//shift+^ 定位到句首
//shift+- 定位到句首
//0 //移动到行首

###按单位移动
//w以单词/字符为单位向右移动,单词头+符号
//nw 移动n个单位
//W:只跳到单词头,不跳符号

//b以单词/字符为单位向左移动(back) ,单词头+符号
//nb 移动n个单位
//B ,只跳到单词头,不跳符号

//e 移动到单词尾,空格前 ,单词尾+符号
//E 只跳单词尾,不跳符号

% 光标移动到匹配的字符(括号什么的一对符号)处。(),[],{},<>。%: goto match

+ 光标移动到下一列的非空白字符 -- 慢慢移动
- 光标移动到上一列的非空白字符
[[ / ]] / (( /)) // 快快移动

//shift+~ 大小写切换
//r 替换光标所在字符, nr 连续换n个 // 按r后输入需要替换的字符
//shift+r 进入替换模式 ,输入会替换掉原有字符

1、翻整页命令
Ctrl + f 键 (f 的英文全拼为:forward)
Ctrl + b 键 (b 的英文全拼为:backward)

2、翻半页命令
Ctrl + d 键 (d 的英文全拼为:down)
Ctrl + u 键 (u 的英文全拼为:up)

//卡死可能的解决方案--ctrl+q
}

vim插入模式
{

$ #为注释

}

vim buffer
{{{
在不同文件buffer间切换
用 vim file1.txt file2.txt ... 命令同时打开多个文件,或者在 vim 里面用 :edit 命令再打开其他文件时,会有多个文件buffer,可以不用退出 vim 就同时编辑多个文件。

可以用下面命令在不同文件buffer间切换:

:bn
切换到下一个文件
:bp
切换到上一个文件
:ls
打印文件buffer的列表,带编号
:b [N]
切换到第N个文件,例如 :b 3 命令切换到第3个文件。文件编号可以用 ls 命令查看
:b {bufname}
通过文件名切换到 bufname 对应的文件,输入文件名时,可以用Tab键补全。
使用Tab键补全时,每按一次Tab键,就会补全一项。如果不小心跳过了想要打开的文件名,可以用 CTRL-P 键返回到前面的项。
:bnext
:bprevious
:blast //bl
:bfirst //bf

:badd test5 //ba
:bdelete test4 //bd

}}}

vim行号/相对行号
{
:set nu //显示行号
:set nonu //取消行号
:set rnu //显示相对行号
:set nornu //取消显示相对行号
}

vim 窗口控制
{

//同时显示多个文件
:sp //水平切分窗口
:vsp //垂直切分窗口

ctrl+6 //打开的文件循环切换

:bn //下一个文件
:bp //上一个文件
:ls //列出打开的文件,带编号
:b1~n //切换至第n个文件 对于用(v)split在多个窗格中打开的文件,这种方法只会在当前窗格中切换不同的文件

ctrl+w+w //循环切换
ctrl+w+hjk //光标到目标方向的窗口

ctrl+w+HJKL //移动所在窗口位置

ctrl+r/R/x //位置对称对换

//上下窗口
ctrl+w+[num]+ - //窗口大小减小num行,默认为1
ctrl+w+[num]+ +(带shirt) //窗口大小增加num行
ctrl+w+ =(不带shift) //窗口大小恢复相等

//左右窗口
<
>

ctrl+w+shift+_ //上下窗口最大化
ctrl+w+shift+| //左右窗口最大化

ctrl+W c 关闭当前窗口
:only 仅保留当前分屏
:hide 关闭当前分屏
}

# yum install -y vim //安装vim

//vim打开文件
# vim 文件 //用vim打开文件

# vim // 直接打开vim -- 测试是否安装vim -- 目前基本上所有云服务器默认都装了vim

$ vim的配置文件每个用户有一个, linux配置文件所有用户共享

$ vim的配置文件名字为.vimrc
// vim配置文件用双引号的其中一个"来注释
// vim的配置一行命令就是一个配置

$ vim的插件目录名字为.vim

70 """"""""""""""""""""""" 按键映射和快捷键提示
271 " 跳转到定义
272 nnoremap <c-k> :YcmCompleter GoToDefinitionElseDeclaration<CR>
273 " 返回到跳转前的位置
274 nnoremap <c-l> <c-o>

$ 自动化配置命令
curl -sLf https://gitee.com/HGtz2222/VimForCpp/raw/master/install.sh -o ./install.sh && bash ./install.sh

$ 不使用table制表,使用空格最好,不同平台table占位不一样 -- 或者把\t制表符改成空格占用

vim寄存器
命令模式
# "3yy //复制当前行到3号寄存器
# "ap //粘贴a寄存器的内容
# "3p //粘贴3号寄存器的内容
//寄存器可以起名字,数字,字母 ...,
//默认是无名寄存器,即直接yy,p这些操作
# :register //查看寄存器
# :reg //查看寄存器缩写
小写字母:引用有名寄存器,会覆盖该寄存器的原有内容
大写字母:则会将新内容添加到该寄存器的原有内容之后
//系统剪贴板 "+ 寄存器 //应该是能粘贴到其他文件 -- 目前不会用
//差不多够用了,前面带"才是引用寄存器

//7

//linux编译器
GCC编译C语言
G++编译C++

gcc命令选项
-E 只激活预处理,这个不生成文件,你需要把它重定向到一个输出文件里面
-S  编译到汇编语言不进行汇编和链接
-c  编译到目标代码
-o 文件输出到 文件
-static 此选项对生成的文件采用静态链接
-g 生成调试信息。GNU 调试器可利用该信息。
-shared 此选项将尽量使用动态库,所以生成文件比较小,但是需要系统由动态库.
-O0
-O1
-O2
-O3 编译器的优化选项的4个级别,-O0表示没有优化,-O1为缺省值,-O3优化级别最高
-w  不生成任何警告信息。
-Wall 生成所有警告信息。

C语言/GCC

$ gcc默认是C89
# gcc ... -std=c99 //修改GCC执行C99标准
//gcc/g++默认生成的可执行程序是release版本
# gcc ... -g //修改为debug版本

G++安装
yum -y install gcc+ gcc-c++ //必须这样才可以

// gcc g++都不需要写上头文件 -- 头文件在预处理阶段会自动在当前目录或库中寻找.c文件中所include的文件,并拷贝到c文件中,所以不用带.h文件

$$ 程序的翻译
1.预处理(头文件展开(合并到成我们的代码),条件编译,宏替换,去注释)
//预处理后还是C语言
$ -E 执行到预处理结束就停下
组合 # gcc -E 源文件 -o 文件.i //将预处理后的文件重命名到新文件,一般为.i文件

2.编译 -- 将C语言编译成汇编语言
# gcc -S .c文件 //从头开始,知到编译结束后停下 -- 默认自动生成.s文件
# gcc -S .i文件 //从预处理后的文件开始 -- 默认自动生成.s文件
# gcc -S .i/.c文件 -o 新文件 //自定义.s文件
$ .s文件是汇编文件

3.汇编 -- 将汇编语言翻译成 可重定位目标二进制 文件 -- 该二进制文件不可被执行bin/obj..
// 只翻译我们实现的代码 -- 即我们调用的代码不做处理
# gcc -c .c/.i/.s文件 //生成.o文件 -- 二进制文件 -- 对等windows的.obj文件
# gcc -c 文件 -o 重命名 // 自定义.o文件
$ 一般情况,有几个源文件,就有几个.obj文件

4.链接 -- 将程序和对应的库链接起来
//将我们自己形成的.obj文件和对应的库文件某种合并,形成可执行程序
# gcc .o/.c/... 文件 //链接
# gcc .o文件 //链接 -- gcc会自动识别 ,不需要命令选项了

$ 记忆: 命令选项为ESc键 ,生成的文件为.iso

//gcc
# gcc -o 命名 源文件 // 编译源文件并命名 , 只要命名在-o后面即可
# gcc 源文件 -o 命名 //

//宏可以没有值

//条件编译 -- 就是一个宏版本的if-else
#ifdef 宏 --如果该宏被定义,则执行 -- #define (宏)关键字..
//...
#else --否则执行这条
//...
#endif

//ifndef 是如果宏没有定义 ,即ifdef的否定

# ldd 可执行文件 //查看看可执行文件链接的库

$ linux的C语言头文件库位于 /usr/include

$ 库分两种 -- 库也是文件 -- linux下特有的
1.静态库: libXXXXXXXX.a

2.动态库: libXXXXXXXX.so

$ linux识别库:去掉前缀lib,去掉后缀,得到的就是库的名字,例如库/lib64/libc.so.6 -> libc-2.17.so的名字为c-2.17 <--> C语言的C标准库

$ windows下静态库为.lib文件 ,动态库为.dll文件 -- 两系统库体系不一样,原理一样

$ 代码运行必须要有语言的头文件和库文件

$ 证明linux的大部分命令是c语言写的 -->
# ldd ../命令 //看链接的库是否有c语言的c标准库 -- 前提是动态链接
//not a dynamic executable -- 非动态链接提示

// 链接是由编译器完成的,编译器负责寻找库,并链接上

$ 动态库 == 共享库
//只有只读属性 ,一般一个系统里只有1份

$ 动态链接:把库所在的地址拷贝到程序里
$ 静态链接:把程序需要的库直接拷贝到程序中

$ 动态库:专门让编译器,对用户程序进行动态链接的
$ 静态库:专门让编译器,对用户的程序进行静态链接的

$ 静态库的优点:健壮性强. 缺点:程序体积,内存/磁盘开销大,拷贝速度慢
$ 动态库的优点:程序体积小,节省空间,速度快 缺点:不够安全

$ 静态库VS动态库:linux默认使用的是动态链接

$ file命令和ldd命令搭配使用
# file 可执行文件 //查看可执行文件信息 --

//dynamically linked 动态链接
//statically linked 静态链接

$ /usr/bin/ld: cannot find -lc错误
//原因:在新版本的linux 系统下安装 glibc-devel、glibc和gcc-c++时,都不会安装libc.a. 只安装libc.so. 所以当 使用-static时,libc.a不能使用。只能报找不到libc了。
//解决:yum install glibc-static
//C++:yum install glibc-static libstdc++-static -y

$ LSB:linux中lsb是指linux标准基础,是“Linux Standards Base”的缩写,LSB是Linux标准化领域中事实上的标准,制定了应用程序与运行环境之间的二进制接口,保证了LINUX发行版同LINUX应用程序之间的良好结合。

$ ELF是linux下的可执行程序 ,对应windows的exe

// linux项目自动化构建工具make和makefile --////生成一个可执行程序
{

//make是个命令,makefile是个文件(m不区分大小写,Makefile也可以)

$ makefile一般放在当前源码路径下

$ makefile是一个围绕依赖关系和依赖方法构建的自动化编译的工具

$ 创建makefile文件语法
依赖关系 //语法中 目标文件:依赖文件列表 -- 目标文件依赖于依赖文件 -- 依赖文件可以有多个,用空格分隔
依赖方法 //语法块要求开头必须是制表符table
依赖关系
依赖方法

$ 依赖关系中,目标文件对应的依赖文件列表可以是空

# make命令的使用
1.默认第一个依赖关系不需要带目标文件,直接make就能执行一个依赖关系的依赖方法
2.要执行其他依赖关系,需要make 目标文件

$ 多依赖关系/传递依赖关系使用栈结构(其他语法实现大多是栈结构),后进先出,--第一行依赖关系先入栈,后面依次入栈 -- 直到满足起始条件
// 入栈过程会带着各自的依赖方法进栈

$ clean: //clean:是依赖关系,clean是目标文件,虽然他没有依赖文件.只要是依赖关系都可以有自己的依赖方法

符号学习:
1. $@ // 永远表示目标文件,依赖关系中冒号的左边
2. $^ // 表示依赖文件列表,依赖关系中冒号的右边

演示1:
out_name:src_file //out 依赖于src
gcc -o out_name src_file //制表符开头
.PHONY:clean
clean:
rm -f out_name //

演示2: //传递依赖关系
out:out.o
gcc -o out out.o
out.o:out.s
gcc -o out.o out.s -c
out.s:out.i
gcc -o out.s out.i -S
out.i:2.c
gcc -o out.i 2.c -E
.PHONY:clean //伪目标:总是被执行的
clean:
rm -f out
rm -f out.o
rm -f out.s

$ 使用make命令
# make //默认只执行第一组依赖关系,执行完第一组就终止 -- 执行其他依赖关系需要make+其他命令选项 / 第一条也可以加上命令选项(只有第一条可以省略)
# make clean //执行makefile中的clean语句块

//执行make命令时,会默认在当前目录去寻找makefile/Makefile文件,然后分析,处理... -- make和makefile的关系

//phony 假的 [ˈfoʊni] -- 假执行 -- 没执行 --
$ .PHONY: //make命令关键字 -- 作用:"总是被执行的" -- 功能是每次都会重新执行,无论是否已被执行过
//linux提示::make: `out' is up to date. -- 意思是已经是最新的执行了 ,出现这条提示说明,make命令没有被执行,即:不是"总是被执行的"

$ 在Makefile中,不加.PHONY的目标也可以是伪目标,这是因为Makefile默认将没有依赖关系的目标视为伪目标。\
伪目标通常表示一组操作或任务,而不是用于生成文件的目标。

//make是怎么检测源码有没有更新过? make通过检查源代码修改和可执行程序的生成时间来决定要不要执行,
// -- 因为同一版本的可执行程序永远是在源代码编写完成后才有的,即只要新的源代码的修改时间晚于对应的可执行程序,则说明程序不是最新的了
//扩展:vs2019下有时编译出问题,就清理项目再生成一次 -- 因为很多文件之前编译过了,编辑器不再重复编辑,这就有可能出问题,所以重新清理一下可能有效果

# touch 已存在的文件 // 把已存在的文件的所有时间都更新成最新时间 -- 摸一下就变了
$ touch后make就能再执行了

$ 对于多.c文件的makefile处理
{
out:main.c prog.c //依赖文件列表
gcc -o out main.c prog.c //多个.c文件
.PHONY:clean
clean:
rm -f out
}
--C语言include""会先扫描当前文件夹再扫描其他文件夹 -- 目前都放在同一目录就可以,
--头文件在预处理阶段会自动地拷贝到c文件中,所以不用带.h文件,只要.c文件即可

}

makefile{ //生成多个可执行程序

makefile文件演示:
CC = g++
CFLAGS =
LDFLAGS = -std=c++11

FILE1 = server
FILE2 = client

//makefile中,第一组依赖关系就是要构建的目标文件
.PHONY:all
all: server client //让all只有依赖关系,没有依赖方法,即不做任何的构建过程

//然后通过执行依赖项的任务从而生成两个目标文件

server: server.cc
$(CC) $(LDFLAGS) -o $@ $^

client: client.cc
$(CC) $(LDFLAGS) -o $@ $^

# .PHONY:clean //加不加无所谓,在Makefile中,不加.PHONY的目标也可以是伪目标,这是因为Makefile默认将没有依赖关系的目标视为伪目标。
clean:
rm -f $(FILE1) $(FILE2)

}

linux头文件类

$ unistd.h //linux中类似微软windows.h的库
{
unistd 是 "Unix Standard" 的缩写,它是一个C标准库头文件,主要用于提供对POSIX(Portable Operating System Interface for Unix)标准中定义的各种系统调用和常量的访问。unistd.h 头文件在Unix和Unix-like操作系统上广泛使用,用于实现与系统相关的操作,包括文件、I/O、进程管理等。

unistd.h 提供了许多与系统调用相关的函数和常量,包括但不限于:

文件操作: 通过 open()、close()、read()、write() 等函数来进行文件操作。

目录操作: 使用 opendir()、readdir() 等函数来进行目录操作。

进程控制: 使用 fork()、exec*()、wait*() 等函数来创建和管理进程。

环境变量: 使用 getenv() 和 setenv() 等函数来处理环境变量。

系统调用: 通过 syscall() 等函数可以直接调用底层系统调用。

常量定义: 包括文件描述符、错误码、路径最大长度等常量的定义。

系统资源限制: 使用 getrlimit() 和 setrlimit() 等函数来获取和设置系统资源限制。

unistd.h 是C标准库的一部分,为编程人员提供了与底层操作系统交互的接口,可以执行文件、进程、I/O 等各种操作。这个头文件允许程序在Unix和Unix-like操作系统上编写可移植的系统调用和操作系统相关代码。
}

fcntl.h
{
fcntl 是 "file control" 的缩写,表示文件控制。

<fcntl.h> 是一个C标准库头文件,通常在C和C++程序中使用,用于提供文件控制相关的函数和常量。这个头文件主要用于进行文件操作、文件描述符的控制以及文件锁定。以下是一些 <fcntl.h> 头文件中主要功能和常量的示例:

文件打开和创建: <fcntl.h> 包含了常量,例如 O_RDONLY(只读)、O_WRONLY(只写)、O_RDWR(读写),用于指定文件打开模式。

文件描述符控制: 这个头文件包含了函数如 open()、creat()(用于创建文件)、close() 以及 dup() 和 dup2(),用于操作文件描述符。

文件锁定: 使用 <fcntl.h> 中的函数来设置和管理文件锁定,以确保多个进程不会同时修改同一个文件,避免数据损坏。

I/O 操作: 包括 read() 和 write() 等函数,用于读取和写入文件。

文件属性和状态: <fcntl.h> 包含了一些与文件属性和状态相关的常量,如 F_GETFL、F_SETFL,用于获取和设置文件状态标志。

文件控制: 这个头文件中的常量和函数可以用于文件的控制操作,如 fcntl() 函数可用于改变已打开文件的属性或状态。

文件同步: 包括 fsync() 和 fdatasync() 等函数,用于刷新文件缓冲区,将数据写入磁盘。

<fcntl.h> 头文件是在Unix和Unix-like操作系统上广泛使用的,用于进行底层文件和文件描述符的控制。通过这个头文件,程序可以实现文件的读写、锁定、属性设置等操作,从而满足各种文件处理需求。
}

$ man 3 //linux 的C/C++语言手册

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
linux中ctrl+s是暂停终端输入 -- 作用就是不能输入了,堵塞 --[锁定终端] //此时输入的数据都缓存在缓冲区中 -- 感觉很危险
-- 通过ctrl+q恢复 -- 恢复屏幕输出[解锁终端]
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

$ sudo不能由普通用户直接执行,必须是信任的用户才可以
//用户 is not in the sudoers file. This incident will be reported. //xx用户不在sudoers文件里,这个严重事件将被报告
$ sudoers路径:/etc/sudoers
//-r--r-----. 1 root root 4358 Dec 19 2022 sudoers //默认情况任何一个普通用户都没有权限修改,最多只有读权限 -- 只有root能修改

$ 增加信任用户:
.进入到/etc目录 ,打开sudoers文件,
.找到Allow root to run any commands anywhere所在行 //新机器一般在100行左右
.在下方找到root ALL=(ALL) ALL,然后复制一份在下一行
.把root改成用户名,即:用户 ALL=(ALL) ALL

//8

1.认识\r\n
//c语言中字符分为a.可显字符(能够显示输出的) b.控制字符('\n','\t'等)
//认识换行-回车 :平常中新起一行是从当前行的位置进到下一行的行首,而计算机中,这一步其实是由两步操作完成的:1.进到下一行的同样位置 2.回到行首 (或者先回到行首再进下一行
//即 \n\r 或 \r\n
//而\n叫做换行(进到下一行的同样位置) \r叫做回车(回到行首)
// 一般编译器\n都会合并\n\r一起,实现新起一行的操作

2.缓冲区概念

\n在很多语言中具有刷新缓冲区的作用,即遇到\n会立刻将缓冲区的数据输出

//缓冲区有自己的刷新策略:
行缓冲:遇到换行符\n就刷新缓冲

缓冲区刷新方案有很多种:无缓冲,行缓冲,全缓冲..
//缓冲还有使用主动调用函数如fflush(stdout)刷新,进程退出时由系统自动刷新

\r的作用是将控制台的光标移动到行首
\r的神奇现象:如果在linux中打印一个长度小于命令提示符的数据,会发现没有打印的效果(打印的东西看不到) -- 其实就是光标移到了行首,然后命令提示符覆盖打印的数据
//发现 -- 在\r后的输出会把光标所在位置的原字符覆盖掉 --

凡是向显示器打印的内容都是字符,一个一个的字符输出-- putc() -- 所以叫做 字符设备

$ 缓冲区处理方案与平台有关,不同不太不同处理方案

linux第一个小程序 -进度条

printf(" [\033[44m%-s\033[0m\r",bar);//c语言颜色为 \033[数字m "字符串" \033[0m //0m:截至关闭颜色

//git

gitee和github区别:底层都是基于git的网站化git管理服务端

$ 查看git版本 -- 查看git是否安装
# git --version

sudo yum install -y git

# git clone 克隆地址
//输入用户名:注册gitee/github的手机号或用户名或完整邮箱 -- 注册的账号
//账号密码

删除git仓库 // .git就是仓库
# rm .git -rf

# git add . //把当前目录下所有文件提交到暂存区
# git add [file1] [file2] ... //单独添加多个文件到暂存区 ,以空格分隔
# git add [dir] // 添加目录
# git add -A //这个命令会递归地将当前目录及其子目录中的所有更改和已删除的文件添加到暂存区。:解决add不了的问题

# git commit -m "修改信息" //提交到本地仓库 -- 提交暂存区到仓库区
# git commit [file1] [file2] ... -m [message] //提交暂存区的指定文件到仓库区
# git commit -a //提交工作区自上次commit之后的变化,直接到仓库区
# git commit -v //提交时显示所有diff信息
# git commit --amend -m "message" //使用一次新的commit,替代上一次提交(重做上一次commit),如果代码没有任何新变化,则用来改写上一次commit的提交信息
//修改未push的,最后一次的commit可以用
// 不要随便重做 -- 把持不住

//提交代码必做
# git config --global user.name "提交用户名" //给别人看的
# git config --global user.email "提交邮箱"
# git config --list //查看提交用户和邮箱
# git config --global --list

# git status //显示有变更的文件
# git log //显示当前分支的版本历史, 查看提交日志 --按q退出历史记录列表
# git log --stat //显示commit历史,以及每次commit发生变更的文件
...

# git branch 列出所有本地分支
# git branch -r 列出所有远程分支
# git branch -a 列出所有本地分支和远程分支
# git branch [branch-name] 新建一个分支,但依然停留在当前分支
# git checkout -b [branch] 新建一个分支,并切换到该分支
# git checkout [branch-name]切换到指定分支,并更新工作区
...

远程同步
# git fetch [remote]//下载远程仓库的所有变动
# git remote -v //显示所有远程仓库
# git remote -v //查看已添加的远程仓库
# git pull //取回远程仓库的变化,并与本地分支合并
# git push //上传本地指定分支到远程仓库

git clean
...
-----------------------------------
Git常用命令大全:git命令基本用法
https://blog.csdn.net/hejinde/article/details/131229840

解决git每次提交和拉取代码需要输入用户名和密码问题
输入以下命令行:
# git config --global credential.helper store //之后等待下一次输入账户密码操作后(自动记住账号密码)即可

# git rm 文件 //
# git rm [file1] [file2] ... //删除工作区文件,并且将这次删除放入暂存区
# git rm --cached 文件 //文件从暂存区域移除,但工作区保留:(工作区就是物理文件,暂存区是add后的区域.本地仓库是commit后的)
# git rm -r --cached 文件名 //遍历目录

$ 提交退回
# git reset

$ git如果是push到别的平台则需要的是邮箱+密钥
$ git如果是push到自己的平台,则只需密码

$$ git的问题解决:

一.git删除文件后提交不了:
如果删除了文件,则命令git会提交失败,此时必须要使用命令git rm删除掉远端中刚刚在本地删除的文件,然后才能提交

二.git恢复本地删除文件
git log查看commit 记录,
git checkout <commit> <绝对/相对路径>
例:git checkout c3437c4c2ea505ab948623b0177e8f5049fa4e06 . //恢复某次提交到当前目录

三.
git add 时出现: LF will be replaced by CRLF the next time Git touches it
//https://blog.csdn.net/weixin_44786530/article/details/129735762

//颜色.....

一般系统默认的提示符形式是:[username@host 工作目录]$

$ 默认命令提示符规则 # echo $PS1 //[\u@\h \W]\$
@ : #就是普通字符
\d :#代表日期,格式为weekday month date,例如:“Mon Aug 1”
\H :#完整的主机名称
\h :#仅取主机的第一个名字 //主机名
\t :#显示时间为24小时格式,如:HH:MM:SS
\T :#显示时间为12小时格式
\A :#显示时间为24小时格式:HH:MM
\u :#当前用户的账号名称 //用户名
\v :#BASH的版本信息
\w :#完整的工作目录名称
\W :#利用basename取得工作目录名称,所以只会列出最后一个目录
#:#下达的第几个命令
$ :#提示字符,如果是root时,提示符为:# ,普通用户则为:$
-----------------------------------
https://blog.51cto.com/u_11566825/2063370

2.设置颜色
在PS1中设置字符颜色的格式为:
[\e[F;Bm],其中“F“为字体颜色,编号为30-37,“B”为背景颜色,编号为40-47。颜色表如下:

[\e[F;Bm]需要改变颜色的部分[\e[0m]
开始颜色输入:[\e[F;Bm]
结束颜色输入:[\e[0m]
    F Bm
    30 40 黑色
    31 41 红色
    32 42 绿色
    33 43 黄色
    34 44 蓝色
    35 45 紫红色
    36 46 青蓝色
    37 47 白色
    
设置特殊显示 
     0 OFF,关闭颜色
     1 高亮显示 //亮瞎狗眼
     4 显示下划线
     5 闪烁显示 //跑马灯 黑闪黑闪
     7 反白显示 //背景与字体颜色反过来
     8 颜色不可见
-----------------------------------
https://www.cnblogs.com/ggzhangxiaochao/p/13141437.html

//修改主机名
# sudo hostnamectl set-hostname 新名字(不能是中文)

$ 我的设置: # PS1="\e[36m\][\u@\h \W\t]\\$\[\e[0m]" //复制到相应文件中

$ 写入~/.bash_profile或~/.bashrc只对当前用户生效。
$ 写入/etc/profile或/etc/bashrc对全部用户生效

$ source 命令:常用于重新执行刚修改的初始化文件。如/etc/profile , bash_profile, bashrc?通过 source命令 在不重启的情况下生效。//刷新
$ . 命令 //和等价于source命令,让配置文件立即生效
PS1="[\e[37;1m] [ [\e[31;1m]\u [\e[36;1m]@ [\e[33;1m]\h [\e[35;40m]\W[\e[37;1m] ] [\e[33;1m]\$[\e[0m]

//GDB gdb

# sudo debuginfo-install glibc-2.17-326.el7_9.x86_64 libgcc-4.8.5-44.el7.x86_64 //环境

readelf -S 文件 //读elf格式的可执行程序的二进制文件

# gdb 文件 //backtrace
# quit或q //退出gdb

# gdb 有debug信息的可执行文件
# l //list -- 显示部分代码
# l+n //从哪一行开始显示
# l file:行号/函数名 //
# b 行号 //breakpoint -- 给哪行打断点
# d/delete 断点编号 //删除断点
# d breakpoints // 删除所有断点
# r // run//执行 -- 到断点处停下来
# info b //查看所有打的断点 -- 断点有编号Num,依次递增,不会循环 ,直到退出gdb
# disable Num //暂停断点
# disable breakpoint Num// 全称
# enable Num //启用断点 -- 使能
# enable breakpoint Num// 全称
# n/next //逐过程
# s/step //逐语句 --步骤 - 可能会进到库的代码 -- 所以要注意用n跳出去
# until 行号 //在函数内,指定位置跳转,执行完区间代码.直接运行到指定行 -
# finish // 运行完当前函数
# c/continue //运行到下一个断点
# f/frame //简写f, f 0 切换到栈0,即栈顶

# set var:修改变量的值 -- 用的情况比较少,在循环里i,j什么的可能好用

//命令中的文件是源文件,不是可执行程序 -- 可能有多个源文件,所以能带文件名 --

//调用函数要压栈 --
# bt/backtrace //查看调用栈
#0 addToTop (top=100) at gdb.c:6 //压栈
#1 0x00000000004005bc in main () at gdb.c:22 //栈底

# p 变量 //查看当前变量的值
# display 变量 //长监视 -- 每次都会自动刷新 -- 会生成和断点一样的编号 (支持:内置类型,自定义类型,stl...)
# undisplay 编号 // 需要编号才能删除
# info display // 查看所有长监视的变量
# info/i locals // 查看局部变量的值

---- 所有的info都可以简写成i , i+首字符可以提示语法

//指定(可带文件名)关键字打断点: #b (文件名:)关键字 //
//遇到不能打断点的地方,断点对进到不能打的下下....一行,直到遇到能打断点的位置

//breakpoint already hit 1 time //断点已经命中一次
//no breakpoint or watchpoint //没有断点或观察点
//watchpoint //观察点 -- 没有被激活的

//gdb会自动记忆最近一次的命令 -- 回车重复上次命令 -- 如list后回车会将剩下的代码依次打印出来

//测试人员一般只要release的可执行程序
//gcc/g++默认生成的可执行程序是release版本\
# gcc ... -g //修改为生成debug版本

# readelf -S 可执行文件 //
在Linux下,readelf -S命令用于显示目标文件或共享目标文件的节表信息。
它可以列出目标文件的所有节(section)的信息,包括每个节的名称、类型、大小、偏移量等。其中,节是目标文件中的一些逻辑段,用于存储程序的代码、数据和符号表等信息。
通过readelf -S命令,用户可以快速查看目标文件中包含的各个节的信息,有助于了解程序的结构和调试信息。此外,readelf -S命令还可以用于分析和调试程序,例如确定程序的内存映像、调试符号表等
————————————————
https://blog.csdn.net/m0_65379664/article/details/130382886

# readelf -S elf文件 | grep -i debug // -i忽略大小写,过滤出所有带debug的信息 -- 没有说明不是debug文件

linux基本知识汇总1(基础命令) 20000字汇总的更多相关文章

  1. Linux学习日志第一天——基础命令①

    文章目录 前言 命令的作用及基本构成 关于路径 命令 ls (list) 命令 pwd (print working directory) 命令cd (change directory) 命令 mkd ...

  2. linux远程方式,以及基础命令

    最近准备学习linux系统,购买了阿里巴巴的云服务器,系统为CentOS. 一.连接实例 1.使用管理终端. 这是阿里巴巴云服务器管理控制台,需要登录阿里巴巴,找到自己实例后,点击右侧远程连接即刻. ...

  3. Linux(2):基础命令

    linux 的规则: 1. linux 命令行组成结构:如下 [root@neo ~]# [用户名@主机名 当前工作路径]# ~ 用户的家目录 2. linux系统命令操作语法的格式(命令的样子): ...

  4. linux之vi编辑器的基础命令

    1,假如要在这个php文件的phpinfo.php;之后加入一行,我们可以先按键盘的"a",光标就会跳转到之前绿色光标之后,也就是说,"a"是代表在当前光标之后 ...

  5. Linux基础知识与基础命令

    Linux基础知识与基础命令 系统目录 Linux只有一个根目录,没有盘符的概念,文件目录是一个倒立的树形结构. 常用的目录功能 bin 与程序相关的文件 boot 与系统启动相关 cdrom 与Li ...

  6. Linux基础知识第二讲,文件目录命令使用

    目录 一丶Linux终端使用技巧. 1.自动补全 Tab技巧. 2.使用输入过的命令 二丶Linux 目录知识 1.linux目录的特点 2.ls 隐藏文件的查看 3.ls 常用选项 4.通配符的配合 ...

  7. Linux基础命令汇总109条

    1       文件管理 1.1     basename 1.1.1     功能说明 从文件名中去掉路径和扩展名 例:basename include/stdio.h .h Output &quo ...

  8. 对Linux(Unix)的基础知识归纳

    前言,不论是原生APP(Android&IOS),还是大型架构级基础环境(.NET&J2EE,或LAMP阵营等), 基本都不可避免的涉及到Linux(Unix),故还是觉得有必要把自己 ...

  9. 【分享】4412开发板-嵌入式Linux开发须要掌握的基础知识和技能

    本文转自迅为电子论坛:http://www.topeetboard.com 1.Linux 基础 安装Linux操作系统 Linux文件系统 Linux经常使用命令 Linux启动过程具体解释 熟悉L ...

  10. Linux最常用的基础命令

    Linux最常用的基础命令个人总结 计算机基础知识: 32bit和64bit系统的区别.系统运行机制 32bit=内存的最大寻址空间是2**32,也就是说最大只能使用4GB的内存64bit=内存的最大 ...

随机推荐

  1. 【JS 逆向百例】cnki 学术翻译 AES 加密分析

    关注微信公众号:K哥爬虫,QQ交流群:808574309,持续分享爬虫进阶.JS/安卓逆向等技术干货! 声明 本文章中所有内容仅供学习交流,抓包内容.敏感网址.数据接口均已做脱敏处理,严禁用于商业用途 ...

  2. Rocketmq学习4——Broker消息持久化原理源码浅析

    一丶前言 在<Rocketmq学习3--消息发送原理源码浅析>中,我们学习了消息发送的要点: 本地缓存+rpc 请求namesever + 定时刷新,topic路由信息 负载均衡的选择一个 ...

  3. 【scikit-learn基础】--『回归模型评估』之准确率分析

    分类模型的评估和回归模型的评估侧重点不一样,回归模型一般针对连续型的数据,而分类模型一般针对的是离散的数据. 所以,评估分类模型时,评估指标与回归模型也很不一样,比如,分类模型的评估指标通常包括准确率 ...

  4. [3] 以逆向的角度来看循环语句——do、while、for的比较

    [3] 以逆向的角度来看循环语句--do.while.for的比较 1. do循环 ​ 先执行循环体,后比较判断 #include <stdio.h> int main(int argc, ...

  5. Go中sync.map使用小结

    sync.map 前言 深入了解下 查看下具体的实现 Load Store Delete LoadOrStore 总结 流程图片 参考 sync.map 前言 Go中的map不是并发安全的,在Go1. ...

  6. yarn常用命令

    1. 安装 npm install yarn -g 2. 设置淘宝镜像 yarn config set npmRegistryServer https://registry.npm.taobao.or ...

  7. 营销(marketing)、推广(Promotion)和 运营(Operation)的概念分别是什么?

    首先要明确的原则: 1.你得承认"讨论任何事情之前不弄清楚概念定义就是耍流氓" 2.你得承认"由于每个人的经验学识和理解力的不同,我们常对概念定义产生分歧" 3 ...

  8. Vite4+Typescript+Vue3+Pinia 从零搭建(1) - 项目初始化

    项目代码同步至码云 weiz-vue3-template 前提准备 1. node版本 Node.js版本 >= 12,如果有老项目需要旧版本的,推荐用 nvm 管理node版本. PS C:\ ...

  9. PHP使用cookie做浏览历史记录

    /** * @param $article文章详情 * @param int $count记录数 * tp须引入cookie类 */ function addHistory($article,$cou ...

  10. 从函数柯里化聊到add(1)(2)(3) add(1, 2)(3),以及柯里化无限调用

    壹 ❀ 引 很久之前看到过的一道面试题,最近复习又遇到了,这里简单做个整理,本题考点主要是函数柯里化,所以在实现前还是简单介绍什么是柯里化. 贰 ❀ 函数柯里化(Currying) 所谓函数柯里化,其 ...