Linux中基础开发工具详细介绍
目录
- 软件包管理器
- 什么是软件包
- Linux软件生态
- yum具体操作
- 查看软件包
- 安装软件
- 卸载软件
- 注意事项
- 编辑器Vim
- Linux编辑器-vim使用
- vim的基本概念
- 快速编辑的指令
- 编译器gcc/g++
- 背景知识
- gcc编译选项
- 预处理(进行宏替换)
- 编译(生成汇编)
- 汇编(生成机器可识别代码)
- 连接(⽣成可执⾏⽂件或库⽂件)
- 动态链接和静态链接
- 静态库和动态库
- 自动化构建-make/Makefile
- 背景
- 基本使用
- 推导过程
- 适度扩展语法
- Linux第一个系统程序−进度条
- 补充知识
- 进度条
- git--版本控制器
- 调试器 - gdb/cgdb使用
- 样例代码
- 预备
- 常见使用
- 调试技巧
软件包管理器
什么是软件包
• 在Linux下安装软件, ⼀个通常的办法是下载到程序的源代码, 并进⾏编译, 得到可执⾏程序.
• 但是这样太麻烦了, 于是有些⼈把⼀些常⽤的软件提前编译好, 做成软件包(可以理解成windows上
的安装程序)放在⼀个服务器上, 通过包管理器可以很⽅便的获取到这个编译好的软件包, 直接进⾏安
装.
• 软件包和软件包管理器, 就好⽐ “App” 和 “应⽤商店” 这样的关系.
• yum(Yellow dog Updater, Modified)是Linux下⾮常常⽤的⼀种包管理器. 主要应⽤在Fedora,
RedHat, Centos等发⾏版上.
• Ubuntu:主要使⽤apt(Advanced Package Tool)作为其包管理器。apt同样提供了⾃动解决依
赖关系、下载和安装软件包的功能。
Linux中安装软件一般有三种方法
- 源码安装
源码安装的弊端
- 编译依赖复杂:源代码安装通常需要满足一系列编译依赖,包括编译器、开发库、头文件等。如果系统中缺少这些依赖,编译过程会失败。
- 编译时间长:从源代码编译软件通常比安装预编译的二进制文件慢得多,尤其是对于大型软件。编译时间取决于软件的复杂性和系统的硬件性能。
- 缺乏自动更新:预编译的软件包通常由包管理器自动更新,而从源代码安装的软件需要手动更新。如果忘记更新,可能会导致安全漏洞或功能缺失。
- 系统兼容性问题:源代码安装的软件可能与系统的其他组件发生冲突,尤其是当使用了自定义配置或非标准路径时。
- 缺乏统一管理:预编译的软件包由包管理器统一管理,可以轻松卸载、更新或查询依赖关系。从源代码安装的软件则需要手动管理,容易导致系统混乱。
- 配置复杂:源代码安装通常需要手动配置,包括指定安装路径、启用或禁用功能等。这需要用户对软件有较深的了解。
- 可能引入安全风险:如果从不可信的源代码仓库下载软件,可能会引入恶意代码或安全漏洞。
- 软件包安装
软件包安装的弊端
- 缺乏依赖管理:二进制文件通常不会自动处理依赖关系。如果软件依赖于其他库或工具,而这些依赖未安装,软件可能无法正常运行。
- 版本兼容性问题:二进制文件通常针对特定的操作系统版本或架构编译。如果系统环境与编译时的环境不一致,可能会出现兼容性问题。
- 安装路径混乱:二进制文件的安装路径通常由软件开发者决定,可能与系统默认的路径不一致。这可能导致路径冲突或难以管理。
- 缺乏统一管理:直接下载二进制文件安装的软件通常不会被系统的包管理器(如 apt 或 yum)管理。这使得卸载、更新或查询软件信息变得困难。
- 系统配置问题:某些二进制文件可能需要特定的系统配置才能运行,例如环境变量设置、服务启动或用户权限调整。如果这些配置未正确完成,软件可能无法正常工作。
- 包管理器安装(推荐使用,它会自动给我们解决包的依赖性问题)
两个步骤完成:网络下载和安装(其实就是拷贝),会拷贝到默认的路径下,必须使用root权限,所以安装到系统里面,只安装一次,任何人都能使用!
Linux软件生态
- Linux下载软件的过程(Ubuntu、Centos、other)
- 操作系统的好坏评估— 生态问题
一款操作系统背后的配套软件,也算是生态的一环.- 为什么会有⼈免费特定社区提供软件,还发布?还提供云服务器让你下载?
本质也是一种商业模式
base-稳定软件源,epel-扩展源软件源.
稳定软件源的作用
- 保证软件的可信度和稳定性:
稳定的软件源通常提供经过测试和验证的软件包,确保用户下载和安装的软件是安全、可靠且稳定的。
这有助于减少因软件故障或漏洞而导致的系统崩溃或数据丢失等问题。- 提供软件选择和更新的便利:
稳定的软件源包含丰富的软件资源,用户可以根据自己的需求选择合适的软件进行安装。
同时,软件源会定期更新软件包,确保用户能够获取到最新版本的软件,从而享受最新的功能和性能改进。- 优化用户体验:
通过提供稳定、可靠的软件源,用户可以更加便捷地安装、更新和管理软件,从而提升用户体验。
扩展软件源的作用- 增强软件功能:
扩展软件源提供了额外的软件包、插件或模块,这些可以扩展现有软件的功能,使其具备更多实用功能,满足用户多样化的需求。- 提升软件适应性:
随着市场环境的变化和用户需求的不断变化,软件需要快速适应新的应用场景。扩展软件源提供的软件包和插件可以帮助软件在无需大规模修改的情况下快速适应新需求。- 促进技术创新:
扩展软件源为软件的创新提供了更多的可能性。通过引入新的技术、算法或功能模块,软件可以在功能上实现突破,推动技术的不断进步。- 优化资源利用:
扩展软件源允许软件与其他软件或硬件无缝集成,实现资源的共享和优化利用。这有助于提升整体工作效率,降低运营成本。总结,稳定软件源和扩展软件源在软件开发和用户使用中均发挥着重要作用。稳定软件源保证了软件的可信度和稳定性,提供了软件选择和更新的便利;而扩展软件源则增强了软件的功能和适应性,促进了技术创新和资源优化利用。
- 软件包依赖的问题
- 国内镜像源
我的机器,怎么知道下载链接呢?操作系统的内部,会内置链接,更改链接,我们也称之为更改镜像源!
/etc/yum.repos.d/*
(yum源配置文件)
更改yum源
yum具体操作
查看软件包
yum list
通过 yum list 命令可以罗列出当前⼀共有哪些软件包. 由于包的数⽬可能⾮常之多, 这⾥我们需要使⽤grep 命令只筛选出我们关注的包.
注意事项:
• 软件包名称: 主版本号.次版本号.源程序发⾏号-软件包的发⾏号.主机平台.cpu架构.
• “x86_64” 后缀表⽰64位系统的安装包, “i686” 后缀表⽰32位系统安装包. 选择包时要和系统匹配.
• “el7” 表⽰操作系统发⾏版的版本. “el7” 表⽰的是 centos7/redhat7. “el6” 表⽰ centos6/redhat6.
• 最后⼀列, base 表⽰的是 “软件源” 的名称, 类似于 “⼩⽶应⽤商店”, “华为应⽤商店” 这样的概念.
安装软件
Centos
$sudo yum install -y lrzsz
Ubuntu
$sudo apt install -y lrzsz
• yum/apt 会⾃动找到都有哪些软件包需要下载, 这时候敲 “y” 确认安装.
• 出现 “complete” 字样或者中间未出现报错, 说明安装完成.
注意事项:
- 安装软件时由于需要向系统⽬录中写⼊内容, ⼀般需要 sudo 或者切到 root 账户下才能完成.
- yum/apt安装软件只能⼀个装完了再装另⼀个. 正在yum/apt安装⼀个软件的过程中, 如果再尝试用yum/apt安装另外⼀个软件, yum/apt会报错.
- 如果 yum / apt报错, 请自行百度.
卸载软件
Centos
sudo yum remove [-y] lrzsz
Ubuntu
sudo apt remove [-y] lrzsz
注意事项
关于 yum / apt 的所有操作必须保证主机(虚拟机)⽹络畅通!!!
可以通过 ping 指令验证:ping www.baidu.com
编辑器Vim
Linux编辑器-vim使用
vi/vim的区别简单点来说,它们都是多模式编辑器,不同的是vim是vi的升级版本,它不仅兼容vi的所有指令,⽽且还有⼀些新的特性在⾥⾯。例如语法加亮,可视化操作不仅可以在终端运⾏,也可以运⾏于x window、 mac os、 windows。
vim的基本概念
vim的三种模式(其实有好多模式,⽬前掌握这3种即可),分别是命令模式(command
mode)、插⼊模式(Insert mode)和底⾏模式(last line mode)
• 正常/普通/命令模式(Normal mode)
控制屏幕光标的移动,字符、字或⾏的删除,移动复制某区段及进⼊Insert mode下,或者到 last line mode
• 插⼊模式(Insert mode)
只有在Insert mode下,才可以做⽂字输⼊,按「ESC」键可回到命令⾏模式。该模式是我们后⾯⽤
的最频繁的编辑模式。
• 末⾏模式(last line mode)
⽂件保存或退出,也可以进⾏⽂件替换,找字符串,列出⾏号等操作。
在命令模式下,shift+:
即可进⼊该模式。要查看你的所有模式:打开 vim,底⾏模式直接输⼊:help vim-modes
我这⾥⼀共有12种模式:six BASIC modes和six ADDITIONAL modes.
快速编辑的指令
gg
:快速回归光标到第一行开头
shift+g
:快速回归光标到最后一行开头
n+shift+g
:定位到n行
shift+$
:快速回到行尾
shift+^
:快速回到行头
hjkl
:分别代表左,下,上,右,前面都可以带n
w
:以单词为单位,向后移动,前面都可以带n
b
:以单词为单位,向前移动,前面都可以带n
yy
:复制莫一行,前面都可以带n
p
:粘贴某一行,前面都可以带n
dd
:删除某一行,前面都可以带n
r
:替换,r->目标字符,前面都可以带n
shift+r
:进入替换模式,批量化替换
x
:字符左侧删除,前面都可以带n
shift+x
:字符右侧删除,前面都可以带n
shift+~
:大小写字母切换
shift+#
:选中单词,n
逆向查找
u
:撤销历史操作
ctrl+r
:插销u
的操作
注意:一旦退出文件编辑,就无法再进行撤销操作了,如果只是保存,并没有退出,就还可以进行撤销操作!
底行模式
w/q/!/set nu/set nonu
分屏
查找
%s/dst/src
使用vim的小技巧
!command
:在末行模式可以使用这个命令
vim src+n
:打开src文件,光标定位到n
行
编译器gcc/g++
背景知识
- 预处理(进⾏宏替换/去注释/条件编译/头⽂件展开等)
- 编译(⽣成汇编)
- 汇编(⽣成机器可识别代码)
- 连接(⽣成可执⾏⽂件或库⽂件)
gcc编译选项
格式 :
gcc [选项] 要编译的⽂件 [选项] [⽬标⽂件]
预处理(进行宏替换)
- 预处理功能主要包括宏定义,⽂件包含,条件编译,去注释等。
- 预处理指令是以#号开头的代码⾏。
- 实例: gcc -E test.c -o test.i
- 选项“-E”,该选项的作⽤是让 gcc 在预处理结束后停⽌编译过程。
- 选项“-o”是指⽬标⽂件,“.i”⽂件为已经过预处理的C原始程序。
编译(生成汇编)
- 在这个阶段中,gcc ⾸先要检查代码的规范性、是否有语法错误等,以确定代码的实际要做的⼯作,在检查⽆误后,gcc 把代码翻译成汇编语⾔。
- 用户可以使⽤“-S”选项来进⾏查看,该选项只进⾏编译⽽不进⾏汇编,生成汇编代码。
- 实例: gcc -S test.i -o test.s
汇编(生成机器可识别代码)
- 汇编阶段是把编译阶段⽣成的“.s”⽂件转成⽬标⽂件
- 读者在此可使⽤选项“-c”就可看到汇编代码已转化为“.o”的⼆进制⽬标代码了(可重定位目标文件)
- 实例: gcc -c test.s -o test.o
连接(⽣成可执⾏⽂件或库⽂件)
- 在成功编译之后,就进⼊了链接阶段。
- 实例: gcc test.o -o test
动态链接和静态链接
在我们的实际开发中,不可能将所有代码放在⼀个源⽂件中,所以会出现多个源⽂件,⽽且多个源⽂件之间不是独⽴的,⽽会存在多种依赖关系,如⼀个源⽂件可能要调⽤另⼀个源⽂件中定义的函数,但是每个源⽂件都是独⽴编译的,即每个*.c⽂件会形成⼀个*.o⽂件,为了满⾜前⾯说的依赖关系,则需要将这些源⽂件产⽣的⽬标⽂件进⾏链接,从⽽形成⼀个可以执⾏的程序。这个链接的过程就是静态链接。静态链接的缺点很明显:
- 浪费空间:因为每个可执⾏程序中对所有需要的⽬标⽂件都要有⼀份副本,所以如果多个程序对同⼀个⽬标⽂件都有依赖,如多个程序中都调⽤了printf()函数,则这多个程序中都含有printf.o,所以同⼀个⽬标⽂件都在内存存在多个副本;
- 更新⽐较困难:因为每当库函数的代码修改了,这个时候就需要重新进⾏编译链接形成可执⾏程序。但是静态链接的优点就是,在可执⾏程序中已经具备了所有执⾏程序所需要的任何东西,在执⾏的时候运⾏速度快。
动态链接的出现解决了静态链接中提到问题。动态链接的基本思想是把程序按照模块拆分成各个相对独⽴部分,在程序运⾏时才将它们链接在⼀起形成⼀个完整的程序,⽽不是像静态链接⼀样把所有程序模块都链接成⼀个单独的可执⾏⽂件。
动态链接其实远⽐静态链接要常⽤得多。⽐如我们查看下 test 这个可执⾏程序依赖的动态库,会发现它就⽤到了⼀个c动态链接库:
ldd
:命令⽤于打印程序或者库⽂件所依赖的共享库列表。
在这里涉及到⼀个重要的概念: 库
- 我们的C程序中,并没有定义“printf”的函数实现,且在预编译中包含的“stdio.h”中也只有该
函数的声明,⽽没有定义函数的实现,那么,是在哪⾥实“printf”函数的呢?- 最后的答案是:系统把这些函数实现都被做到名为 libc.so.6 的库⽂件中去了,在没有特别指定时,gcc 会到系统默认的搜索路径“/usr/lib”下进⾏查找,也就是链接到 libc.so.6 库函数中去,这样就能实现函数“printf”了,⽽这也就是链接的作⽤
静态库和动态库
- 静态库是指编译链接时,把库⽂件的代码全部加⼊到可执⾏⽂件中,因此⽣成的⽂件⽐较⼤,但在运⾏时也就不再需要库⽂件了。其后缀名⼀般为“.a”
- 动态库与之相反,在编译链接时并没有把库⽂件的代码加⼊到可执⾏⽂件中,⽽是在程序执⾏时由运⾏时链接⽂件加载库,这样可以节省系统的开销。动态库⼀般后缀名为“.so”,如前⾯所述的libc.so.6 就是动态库。gcc 在编译时默认使⽤动态库。完成了链接之后,gcc 就可以⽣成可执⾏⽂件.
- gcc默认⽣成的⼆进制程序,是动态链接的,这点可以通过 file 命令验证。
Linux下,动态库XXX.so, 静态库XXX.a
Windows下,动态库XXX.dll, 静态库XXX.lib
⼀般我们的云服务器,C/C++的静态库并没有安装,如果要使用静态库,需要我们自己安装.
自动化构建-make/Makefile
背景
• 会不会写makefile,从⼀个侧⾯说明了⼀个⼈是否具备完成⼤型⼯程的能⼒
• ⼀个⼯程中的源⽂件不计数,其按类型、功能、模块分别放在若⼲个⽬录中,makefile定义了⼀系列的规则来指定,哪些⽂件需要先编译,哪些⽂件需要后编译,哪些⽂件需要重新编译,甚⾄于进⾏更复杂的功能操作
• makefile带来的好处就是⸺“⾃动化编译”,⼀旦写好,只需要⼀个make命令,整个⼯程完全⾃动编译,极⼤的提⾼了软件开发的效率。
• make是⼀个命令⼯具,是⼀个解释makefile中指令的命令⼯具,⼀般来说,⼤多数的IDE都有这个命令,⽐如:Delphi的make,Visual C++的nmake,Linux下GNU的make。可⻅,makefile都成为了⼀种在⼯程⽅⾯的编译⽅法。
• make是⼀条命令,makefile是⼀个⽂件,两个搭配使⽤,完成项⽬⾃动化构建。
基本使用
实现代码
#include<stdio.h>int main(){printf("hello zx\n"); return 0;}
Makefile文件
code:code.c gcc -o code code.c .PHONY:clean clean: rm code
依赖关系:
code依赖于code.c,code是最终形成的目标文件
依赖方法:
gcc -o code code.c ,就是与之对应的依赖方法
项目清理
• 工程是需要被清理的。
• 像clean这种,没有被第⼀个⽬标⽂件直接或间接关联,那么它后⾯所定义的命令将不会被⾃动执⾏,不过,我们可以显⽰要make执⾏。即命令⸺“make clean”,以此来清除所有的⽬标⽂件,以便重编译。
• 但是⼀般我们这种clean的⽬标⽂件,我们将它设置为伪⽬标,⽤ .PHONY 修饰,伪⽬标的特性是,总是被执⾏的。
make
和make clean
的不同?
- make命令扫描makefile文件的时候,从上到下扫描,默认新成第一个目标文件,所以make不用跟形成的最终目标文件,如果带上也可以.
测试如果我们把顺序交换一下,make默认生成的最终目标文件就会是clean了
.PHONY:clean
是什么?
.PHONY
是修饰符,clean
则是伪目标,被.PHONY
修饰的,总是被执行的!
测试
make clean
可以执行多次
如果code.c
文件没有更改,那么make
只能执行一次!!!
什么叫做总是不被执行呢?
默认老代码不做编译
测试
如果在code前面也加上修饰符呢?总是可被执行的
是如何区分新老代码呢?
stat
是一个用于显示文件或文件系统状态信息的命令,它提供了比 ls -l 更详细的信息,包括文件的权限、所有者、大小、时间戳等。
- 修改文件内容,
Modify
会更改- 修改文件属性,
Change
会更改- 查看文件,
Access
会更改,不是每次查看文件,Access
属性都会修改.一个文件的查看次数会远远大于一个文件内容的次数,如果每次查看文件,都修改Access
属性的话,会造成许多的IO操作.通过
Modify
时间来查看可执行程序与原文件的先后顺序.code.c在code之前,make就不会重新编译code.c文件了.
但是.PHONY
修饰,会忽略时间对比新旧问题.
touch
命令除了创建文件,还可以做什么?
修改文件的时间属性,统一
Modify,Access`,Change
三个时间命令:
touch + 已经创建好的文件
推导过程
code:code.ogcc code.o -o code
code.o:code.sgcc -c code.s -o code.o
code.s:code.igcc -S code.i -o code.s
code.i:code.cgcc -E code.c -o code.i
最后一个文件完成后,再向上出栈!
make
是如何⼯作的,在默认的⽅式下,也就是我们只输⼊make命令。那么:
- make会在当前⽬录下找名字叫“Makefile”或“makefile”的⽂件。
- 如果找到,它会找⽂件中的第⼀个⽬标⽂件(target),在上⾯的例⼦中,他会找到 code这个⽂件,并把这个⽂件作为最终的⽬标⽂件。
- 如果 code⽂件不存在,或是 code所依赖的后⾯的 code.o ⽂件的⽂件修改时间要⽐ code这个⽂件新(可以⽤ touch 测试),那么,他就会执⾏后⾯所定义的命令来⽣成code这个⽂件。
- 如果 code所依赖的 code.o ⽂件不存在,那么 make 会在当前⽂件中找⽬标为
code.o ⽂件的依赖性,如果找到则再根据那⼀个规则⽣成 myproc.o ⽂件。(这有点像⼀
个堆栈的过程)- 当然,你的C⽂件和H⽂件是存在的啦,于是 make 会⽣成 code.o ⽂件,然后再⽤
code.o ⽂件声明 make 的终极任务,也就是执⾏⽂件 code了。- 这就是整个make的依赖性,make会⼀层⼜⼀层地去找⽂件的依赖关系,直到最终编译出第⼀个⽬标⽂件。
- 在找寻的过程中,如果出现错误,⽐如最后被依赖的⽂件找不到,那么make就会直接退出,并报错,⽽对于所定义的命令的错误,或是编译不成功,make根本不理。
- make只管⽂件的依赖性,即,如果在我找了依赖关系之后,冒号后⾯的⽂件还是不在,那么对不起,我就不⼯作啦。
适度扩展语法
设置变量
1 BIN=code //变量2 SRC=code.c3 CC=gcc4 FLAGS= -o5 RM=rm -f //变量可以带空格6 7 .PHONY:test8 test:9 @echo $(BIN) //@符号:不回显依赖方法10 @echo $(SRC) //$(变量名) 等价于 变量的内容 $(SRC) == code.c11 @echo $(CC)12 @echo $(FLAGS)13 @echo $(RM)
如果有多个文件呢?
version1
1 BIN=code2 SRC=code.c3 CC=gcc4 FLAGS= -o5 RM=rm -f6 LFLAGS=-c7 OBJ=code.o8 $(BIN):$(OBJ)9 $(CC) $(FLAGS) $@ $^10 %.o:%.c //把当前路径下所有的.o/.c文件依次展开11 $(CC) $(LFLAGS) $< //%<: 对展开的依赖.c⽂件,⼀个⼀个的交给gcc。 //编译好后,会自动生成同名的.o文件
version2
1 BIN=code2 SRC=$(wildcard *.c)//使⽤ wildcard 函数,获取当前所有.c⽂件名3 #SRC=$(shell ls *c) //相当于在shell里面使用ls *.c命令,采⽤shell命令⾏⽅式,获取当前所有.c⽂件名4 CC=gcc5 FLAGS= -o6 RM=rm -f7 LFLAGS=-c8 OBJ=$(SRC:.c = .o) //将SRC的所有同名.c 替换 成为.o 形成⽬标⽂件列表 9 $(BIN):$(OBJ)10 $(CC) $(FLAGS) $@ $^11 %.o:%.c12 $(CC) $(LFLAGS) $<
Linux第一个系统程序−进度条
补充知识
回车换行?
\n
:换行
\r
:回车
C语言里面的\n
解析成了\n+\r
;
缓冲区问题?
如果没有\n
,想立即刷新缓冲区?
进度条
基础版本
//version1 8 void process_v1() 9 { 10 char num[NUM];//整个进度条数组 11 memset(num,0,sizeof(num)); 12 int cnt = 0; 13 //char buffer[] = {'//','\','|','-'}; 14 const char* buffer = "-/|\\";//标签,即使进度条没有动,这个也在运转,表示进度在持续15 int len = strlen(buffer);//标签字符串的大小 16 while(cnt<=NUM) 17 { 18 //以\r结尾,回车到该行的第一个字符的位置 19 //这里的%需要转移一下 20 printf("[%-100s][%d%%][%c]\r",num,cnt,buffer[cnt%len]);21 fflush(stdout);//printf()不会刷新缓冲区,需要我们自己刷新22 num[cnt] =STYLE;//每次都给进度条增加一个字符 23 cnt++; 24 usleep(50000);//睡眠50000微秒,1秒 == 1000000微秒 25 } 26 printf("\n");27 }
优化
再优化
git–版本控制器
版本控制器
为了能够更⽅便我们管理这些不同版本的⽂件,便有了版本控制器。所谓的版本控制器,就是能让你了解到⼀个⽂件的历史,以及它的发展过程的系统。通俗的讲就是⼀个可以记录⼯程的每⼀次改动和版本迭代的⼀个管理系统,同时也⽅便多⼈协同作业。⽬前最主流的版本控制器就是 Git 。Git 可以控制电脑上所有格式的⽂件,例如 doc、excel、dwg、dgn、rvt等等。对于我们开发⼈员来说,Git 最重要的就是可以帮助我们管理软件开发项⽬中的源代码⽂件!
安装 git
yum install git
在 Github 创建项目
下载项目到本地
复制仓库链接,准备克隆到本地
克隆远端仓库
git clone 远端仓库链接
理解本地仓库
理解.gitignore
文件
三板斧
- git add
将代码放到刚才下载好的⽬录中,将需要⽤ git 管理的⽂件告知 git,最后的 “.” 表⽰当前⽬录
git add [⽂件名]
暂存区可以让我们多次add,并且一次提交到本地仓库中。
git commit
提交改动到本地,提交的时候应该注明提交⽇志, 描述改动的详细内容.
git commit -m "XXX"
提交日志信息,并提交到git仓库
git push
同步到远端服务器上
git push
需要填⼊用户名密码. 同步成功后, 刷新 Github ⻚⾯就能看到代码改动了.
远端仓库和本地仓库内容不同了怎么办?
远端仓库修改了,但是没有同步到本地,本地仓库就不能push,需要pull拉取,同步一下远端仓库的内容。
git pull
把windows和linux想象成两个A和B程序员,都在使用test这个远端仓库,如果A推送了内容到远端仓库,B还能够直接推送内容吗?
A程序员
A对该文件做了修改,并推送到远端仓库
B程序员
B程序员就可以推送了
那么A程序员还可以推送吗?
答案是不可以的,我们也需要拉取一下
总结:远端仓库相比较于任何人,总是最新的!为什么要冲突呢?是为了提醒用户,你的本能仓库该更新了。
调试器 - gdb/cgdb使用
样例代码
#include <stdio.h>
int Sum(int s, int e)
{
int result = 0;
for(int i = s; i <= e; i++)
{
result += i;
}
return result;
}
int main()
{
int start = 1;
int end = 100;
printf("I will begin\n");
int n = Sum(start, end);
printf("running done, result is: [%d-%d]=%d\n", start, end, n);
return 0;
}
预备
- 程序的发布⽅式有两种,
debug
模式和release
模式, Linux gcc/g++ 出来的⼆进制程序,默认是release
模式。- 要使⽤gdb调试,必须在源代码⽣成⼆进制程序的时候, 加上 -g 选项,如果没有添加,程序⽆法被调试。
注意:编译时加上-g选项,在连接时可以不加,带上该选项之后,生成的可执行程序会带有调试信息。
常见使用
开始:gdb code
注意:code是可执行程序,不是源文件。
退出: ctrl + d
或quit
调试命令
常用命令(这里使用的是cgdb,命令基本都是一致的,但cgdb可以看到代码,便于调试)
l(list)
:查看代码(如果代码看的不完整,可以使用enter键)
b+行号
:给哪一行加上断点
info b
:查看断点
r
:从头开始运行,如果程序运行结束,还可以重新调试代码,不用退出cgdb
c
:一个断点运行到下一个断点处
d+断点编号
:删除断点,不加编号,可以直接删除所有的断点
注意:cgdb不退出的话,断点编号与会一直递增!
n(next)
:逐过程调试(会跳过该函数和vs中的F10一样)
s(step)
:逐语句调试(会进入该函数和vs中的F11一样)
bt
:查看当前执⾏栈的各级函数调⽤及参数
finish
:结束该函数的调用
p + 表达式
:查看表达式的值
disable+断点编号
:禁用断点(使之不能),断点存在,但是并不能使用
enable+断点编号
:取消禁用(使之能)
y表示没有被禁用,n表示被禁用了
注意:断点的本质就是对代码进行块级别的划分,以块为单位快速锁定区域。
until+行号
:局部区域快速执行。
display+变量名
:常显示该变量(监视)
undisplay+编号
:取消常显示,不加编号,全部删除
info locals
:查看当前栈帧的局部变量值
调试技巧
watch
watch
:执⾏时监视⼀个表达式(如变量)的值。如果监视的表达式在程序运⾏期间的值发⽣变化,GDB 会暂停程序的执行,并通知使用者。
set var确定问题原因
set var
可以修改变量的值。
条件断点
- 给新打的断点设置条件,添加条件断点
- 已经存在的断点新增条件
相关文章:
Linux中基础开发工具详细介绍
目录 软件包管理器什么是软件包Linux软件生态 yum具体操作查看软件包安装软件卸载软件注意事项 编辑器VimLinux编辑器-vim使用vim的基本概念快速编辑的指令 编译器gcc/g背景知识gcc编译选项预处理(进行宏替换)编译(生成汇编)汇编(生成机器可识…...
浅谈时钟启动和Systemlnit函数
时钟是STM32的关键,是整个系统的心脏,时钟如何启动,时钟源如何选择,各个参数如何设置,我们从源码来简单分析一下时钟的启动函数Systemlnit()。 Systemlnit函数简介 我们先来看一下源程序的注释…...
社交软件频繁更新,UI 设计在其中扮演什么角色?
在当今数字化时代,社交软件已成为人们日常生活中不可或缺的一部分。随着科技的飞速发展和用户需求的不断变化,社交软件更新频率日益加快。在这频繁更新的背后,UI 设计扮演着至关重要的角色,它如同社交软件的 “门面担当” 与 “交…...
SQLMesh 系列教程:解锁SQLMesh的宏与变量魔法
在数据库流水线开发中,代码复用与动态配置是提升效率的核心诉求。SQLMesh以其独特的宏系统与用户定义变量机制,重新定义了SQL生成的灵活性。与传统模板引擎不同,SQLMesh的宏并非简单的字符串替换,而是基于语义理解的智能代码重构—…...
React篇之three渲染
需求:拖拽右侧面板,里面的three模型能够自适应 import { useEffect, useState, useRef } from react import ./App.css import * as THREE from three; import { GLTFLoader } from three/addons/loaders/GLTFLoader.js; import { debounce } from loda…...
PHP与前端框架的无缝集成:最佳实践与案例分析
PHP与前端框架的无缝集成:最佳实践与案例分析 在现代Web开发中,PHP作为后端语言与前端框架的集成已成为一种常见的开发模式。无论是传统的MVC架构,还是现代的SPA(单页应用),PHP与前端框架的无缝集成能够显…...
Redis内存淘汰策略
Redis 是一种高性能的键值存储系统,广泛用于缓存、消息队列等场景。由于 Redis 数据存储在内存中,而内存资源有限,因此需要内存淘汰策略来管理内存的使用。Redis 提供了多种内存淘汰策略,可以根据不同的应用场景选择合适的策略。 …...
Facebook 的框架及技术栈
一、前端框架与技术 React.js 及其生态系统 核心原理与特点 React.js 是 Facebook 开源的用于构建用户界面的 JavaScript 库。它的核心概念是组件化,将用户界面拆分成一个个独立的、可复用的组件。每个组件都有自己的状态(state)和属性&#…...
QT中的布局管理
在 Qt 中,布局管理器(如 QHBoxLayout 和 QVBoxLayout)的构造函数可以接受一个 QWidget* 参数,用于指定该布局的父控件。如果指定了父控件,布局会自动将其管理的控件添加到父控件中。 在你的代码中,QHBoxLa…...
如何学习VBA_3.2.20:DTP与Datepicker实现日期的输入
我给VBA的定义:VBA是个人小型自动化处理的有效工具。利用好了,可以大大提高自己的劳动效率,而且可以提高数据处理的准确度。我推出的VBA系列教程共九套和一部VBA汉英手册,现在已经全部完成,希望大家利用、学习。 如果…...
在 LaTeX 中强制表格位于页面顶部
在 LaTeX 中强制表格位于页面顶部,可以通过以下 多种方法结合使用,按优先级推荐: 方法 1:使用 [!t] 位置限定符 原理:通过 [!t] 强制 LaTeX 优先将表格放置在页面顶部(Top),! 表示忽…...
dify+mysql的诗词助手
目录 数据库表结构: 数据库查询的http服务搭建: 流程引擎搭建: 开始, HTTP查询数据库, LLM数据分析, 直接回复, 效果测试: 下载链接: 数据库表结构:…...
PyTorch 入门学习
目录 PyTorch 定义 核心作用 应用场景 Pytorch 基本语法 1. 张量的创建 2. 张量的类型转换 3. 张量数值计算 4. 张量运算函数 5. 张量索引操作 6. 张量形状操作 7. 张量拼接操作 8. 自动微分模块 9. 案例-线性回归案例 PyTorch 定义 PyTorch 是一个基于 Python 深…...
【视频】SRS将RTMP转WebRTC、HLS流;获取RTSP转其它流
1、安装依赖库 sudo apt install tclsh sudo apt install cmake sudo apt install autotools-dev automake m4 perl sudo apt install libtool2、源码安装 1)下载源码 https://github.com/ossrs/srs/releases/tag/v5.0-r32)配置、编译 ./configure && make -j83、…...
linux中如何查询文件夹大小
在 Linux 中,可以使用 du 命令查看文件夹大小。以下是常用方法: 标题1. 查看文件夹大小 du -sh /path/to/directory-s:显示总大小。 -h:以易读格式(如 KB、MB、GB)显示大小。 标题2:查看文件…...
MySQL增删改查操作 -- CRUD
个人主页:顾漂亮 目录 1.CRUD简介 2.Create新增 使用示例: 注意点: 3.Retrieve检索 使用示例: 注意点: 4.where条件查询 前置知识:-- 运算符 比较运算符 使用示例: 注意点…...
uniapp+Vue3 组件之间的传值方法
一、父子传值(props / $emit 、ref / $refs) 1、props / $emit 父组件通过 props 向子组件传递数据,子组件通过 $emit 触发事件向父组件传递数据。 父组件: // 父组件中<template><view class"container">…...
TDengine SQL 函数
单行函数 数学函数 ABSACOSASINATANCEILCOSDEGREESEXPFLOORGREATESTLEASTLNLOGMODPIPOWRADIANSRANDROUNDSIGNSINSQRTTANTRUNCATE 字符串函数 ASCIICHARCHAR_LENGTHCONCATCONCAT_WSLENGTHLOWERLTRIMPOSITIONREPEATREPLACERTRIMSUBSTRING/SUBSTRSUBSTRING_INDEXTRIMUPPER 转换函数…...
智能三防手持终端破解传统仓储效率困局
在数字化浪潮的推动下,传统仓储管理模式正面临效率低、成本高、错误频发等瓶颈。如何实现精准、高效、智能化的仓储管理,上海岳冉三防智能手持终端机以RFID技术为核心,结合工业级三防(防水、防摔、防尘)设计࿰…...
力扣——K个一组翻转链表
题目链接: 链接 题目描述: 思路: 可以理解为把原链表的每一段进行反转 把链表的每一段看成新链表,单独进行反转,然后再放回原链表 关键是截取k个节点、进行反转后,怎么再和原链表链接起来 我们把截取的…...
5-27 临摹大师-IP-Adapter
前言: 前一节我们主要介绍ControlNet中如何对黑白照片进行上色 主要介绍ControlNet中的IP-Adapter。这个也是一种类似的风格借鉴,类似Reference的能力。 当然IP-Adapter有两点或许可以吸引我们,一个是国人腾讯公司制作的。另一个在速度和效…...
MinIO的预签名直传机制
我们传统使用MinIo做OSS对象存储的应用方式往往都是在后端配置与MinIO的连接和文件上传下载的相关接口,然后我们在前端调用这些接口完成文件的上传下载机制,但是,当并发量过大,频繁访问会对后端的并发往往会对服务器造成极大的压力…...
树莓科技集团董事长:第五代产业园运营模式的深度剖析与展望
第五代产业园运营模式,以创新为核心驱动,强调数字化、网络化和资源整合。树莓科技集团在这一领域具有代表性,其运营模式值得深入剖析。 核心特征 数字化转型:第五代产业园高度重视数字化技术的应用,通过构建数字化平…...
项目组织管理类型-职能式组织和矩阵式组织的区别
在职能式组织和矩阵式组织中,任务分配和人员安排确实有显著的不同,让我们通过以下例子来进一步解释: 职能式组织在职能式组织中,任务通常是根据部门的职能进行下达的。 例如,一家制造公司的组织结构如下: …...
树莓科技(成都)集团:如何铸就第五代产业园标杆
树莓科技(成都)集团铸就第五代产业园标杆,主要体现在以下几个方面: 精准定位与前瞻布局 树莓科技并非盲目扩张,而是精准锚定数字经济发展方向。以成都为起点,迅速构建起全国性的园区版图,体现…...
【Quest开发】手柄交互震动
软件:Unity 2022.3.51f1c1、vscode、Meta XR All in One SDK V72(要提前导入哦) 硬件:Meta Quest3 参考Meta开发文档:https://developers.meta.com/horizon/documentation/unity/unity-haptics-sdk-integrate 这篇官…...
《Transformer如何进行图像分类:从新手到入门》
引言 如果你对人工智能(AI)或深度学习(Deep Learning)感兴趣,可能听说过“Transformer”这个词。它最初在自然语言处理(NLP)领域大放异彩,比如在翻译、聊天机器人和文本生成中表现出…...
数字图像处理与Python语言实现-Box模糊CUDA实现
Box模糊CUDA实现 文章目录 Box模糊CUDA实现1、Box模糊的基本原理2、算法优化:滑动窗口技术3、参数对模糊效果的影响4、Box模糊的优缺点5、与高斯模糊的对比6、实际应用场景7、算法实现7.1 PyCUDA实现7.2 CuPy实现7.3 C++与CUDA实现8、总结在图像处理领域,**Box模糊(方框模糊…...
MAVEN解决版本依赖冲突
文章目录 一、依赖冲突概念1、什么是依赖冲突2、依赖冲突的原因3、如何解决依赖冲突 二、查看依赖冲突-maven-helper1、安装2、helper使用1、conflicts的阅读顺序(从下向上看)2、dependencies as List的阅读顺序(从下向上看)3、de…...
Compose 实践与探索五 —— AnimationSpec
不论是 animateXxxAsState() 还是 Animatable 的 animateTo() 都可以传入 AnimationSpec 以配置动画的规格: Composable fun animateDpAsState(targetValue: Dp,animationSpec: AnimationSpec<Dp> dpDefaultSpring,label: String "DpAnimation",…...
Embedding模型到底是什么?
嵌入模型(Embedding Model)是一种将高维数据映射到低维空间的工具,广泛应用于自然语言处理(NLP)、推荐系统和图像识别等领域。它的核心目标是将复杂的数据(如文本、图像或用户行为)转换为稠密的…...
数据结构(一)——绪论
一、数据结构的研究内容 1.数据的各种逻辑结构和物理结构,以及他们之间的相应关系 2.存储结构的方法,对每种结构定义相适应的各种运算 3.设计出相应的算法 4.分析算法的效率 二、数据结构的基本概念 1.数据(data):…...
VMware虚拟机网络连接模式介绍以及nat模式访问公网实践
在 VMware 虚拟机中,网络配置是非常重要的一部分。VMware 提供了三种主要的网络连接模式,分别是桥接模式(Bridged)、NAT模式(NAT) 和仅主机模式(Host-Only)。每种模式都有其特定的用…...
Selenium Manager和webdriver manager的区别与联系
一、引言 1.1 自动化测试的重要性 在现代软件开发流程中,自动化测试已经成为保证软件质量和提高交付效率的关键实践。随着软件开发周期的缩短和软件复杂性的增加,手工测试已无法满足快速迭代的需求。自动化测试能够快速、准确地执行重复性测试任务&…...
八叉树地图的原理与实现
八叉树与体素图 八叉树地图 八叉树地图是可变分辨率的三维栅格地图,可以自由调整分辨率,如下所示: 根据点云的数量或密度决定每个叶子方块是否被占据 体素图 体素就是固定分辨率的三维栅格地图,如下所示: 根据点云…...
DeepSeek模型本地化部署方案及Python实现
DeepSeek实在是太火了,虽然经过扩容和调整,但反应依旧不稳定,甚至小圆圈转半天最后却提示“服务器繁忙,请稍后再试。” 故此,本文通过讲解在本地部署 DeepSeek并配合python代码实现,让你零成本搭建自己的AI…...
【Linux】浅谈冯诺依曼和进程
一、冯诺依曼体系结构 冯诺依曼由 输入设备、输出设备、运算器、控制器、存储器 五部分组成。 冯诺依曼的设计特点 二进制表示 所有数据(包括程序指令)均以二进制形式存储和运算,简化了硬件逻辑设计,提高了可靠性。 存储程序原理…...
基于深度学习的多模态人脸情绪识别研究与实现(视频+图像+语音)
这是一个结合图像和音频的情绪识别系统,从架构、数据准备、模型实现、训练等。包括数据收集、预处理、模型训练、融合方法、部署优化等全流程。确定完整系统的组成部分:数据收集与处理、模型设计与训练、多模态融合、系统集成、部署优化、用户界面等。详…...
【蓝桥杯】第15届c++B组--R格式
问题描述 小蓝最近在研究一种浮点数的表示方法:RR 格式。对于一个大于 0 的浮点数 dd,可以用 RR 格式的整数来表示。给定一个转换参数 nn,将浮点数转换为 RR 格式整数的做法是: 将浮点数乘以 2n2n; 四舍五入到最接近的整数。 …...
【初阶三】认识C语言—下
【初阶三】认识C语言—下 1.函数2.数组3.操作符3.1算数操作符3.2移位操作符和位操作符3.3赋值操作符3.4单目操作符 4.常见关键字4.1关键字typedef4.2 关键字static 5. define定义常宏6.指针6.1内存6.2取地址操作符& 7.结构体 1.函数 函数就像一个工厂,通过输入原…...
【C#】使用DeepSeek帮助评估数据库性能问题,C# 使用定时任务,每隔一分钟移除一次表,再重新创建表,和往新创建的表追加5万多条记录
🌹欢迎来到《小5讲堂》🌹 🌹这是《C#》系列文章,每篇文章将以博主理解的角度展开讲解。🌹 🌹温馨提示:博主能力有限,理解水平有限,若有不对之处望指正!&#…...
前端学习笔记(三)——ant-design vue表单传递数据到父页面
前言 善用AI,快速解决定位 原理 a-form所在的SFC(单文件)vue中需要将表单数据传递给父页面SFC文件中,使用emit方法 代码 子组件(Form.vue) <template><a-form submit"handleSubmit&qu…...
计算机视觉算法实战——驾驶员玩手机检测(主页有源码)
✨个人主页欢迎您的访问 ✨期待您的三连 ✨ ✨个人主页欢迎您的访问 ✨期待您的三连 ✨ ✨个人主页欢迎您的访问 ✨期待您的三连✨ 1. 领域简介:玩手机检测的重要性与技术挑战 驾驶员玩手机检测是智能交通安全领域的核心课题。根据NHTSA数据࿰…...
C语言(23)
字符串函数 11.strstr函数 1.1函数介绍: 头文件:string.h char *strstr ( const char * str1,const char *str2); 作用:在一个字符串(str1)中寻找另外一个字符串(str2)是否出现过 如果找到…...
Python入门教程:从零开始学习Python编程
引言 Python是一种高级编程语言,因其简洁的语法和强大的功能而广受欢迎。无论你是编程新手,还是有经验的开发者,Python都是一个非常好的选择。本文将带你从零开始学习Python编程,涵盖基础语法、常用库以及一些实用的编程技巧。 目…...
SAIL-RK3576核心板应用方案——无人机视觉定位与地面无人设备通信控制方案
本方案以 EFISH-RK3576-SBC工控板 或 SAIL-RK3576核心板 为核心,结合高精度视觉定位、实时通信与智能控制技术,实现无人机与地面无人设备的协同作业。方案适用于物流巡检、农业植保、应急救援等场景,具备高精度定位、低延迟通信与强环境适应性…...
14.C语言const的使用规范,详细说明
目录 修饰变量 修饰指针 指向常量的指针 常量指针 指向常量的常量指针 修饰函数参数 修饰函数返回值 总结 在 C 语言里,const 是一个类型限定符,它的作用是将变量定义为只读,也就是不允许对其值进行修改,用来修饰函数中的…...
安装操作系统ubuntu-20.04.6-live-server-amd64
一、下载虚拟机软件、远程控制软件及操作系统镜像 下载VMware Workstation: 下载 VMware Workstation Pro 个人免费版(可能会访问不了,那就随便找个能下载的版本安装)下载XShell: XShell 家庭/学校免费版下载ubuntu操作系统 ubuntu-20.04.6-…...
使用 PaddleNLP 在 CPU(支持 AVX 指令)下跑通 llama2-7b或DeepSeek-r1:1.5b 模型(完成度80%)
原文:🚣♂️ 使用 PaddleNLP 在 CPU(支持 AVX 指令)下跑通 llama2-7b 模型 🚣 — PaddleNLP 文档 使用 PaddleNLP 在 CPU(支持 AVX 指令)下跑通 llama2-7b 模型 🚣 PaddleNLP 在支持 AVX 指令的 CPU 上对 llama 系列模型进行了…...
【Golang】第五弹----函数
笔上得来终觉浅,绝知此事要躬行 🔥 个人主页:星云爱编程 🔥 所属专栏:Golang 🌷追光的人,终会万丈光芒 🎉欢迎大家点赞👍评论📝收藏⭐文章 目录 一、函数 1.1基本介绍…...