Linux 软件包管理器 yum
什么是软件包?
在Linux下安装软件, 一个通常的办法是 下载到程序的源代码, 并进行编译, 得到可执行程序 .但是这样太麻烦了, 于是有些人把一些常用的软件提前编译好, 做成 软件包(可以理解成windows上的安装程序) 放在一个服务器上, 通过包管理器可以很方便的获取到这个编译好的软件包, 直接进行安装.
- 软件包 相当于 "App", 而 软件包管理器 相当于 "应用商店"。 而 yum 就是 centos 的软件包管理器。
- yum(Yellow dog Updater, Modifified)是 Linux 下非常常用的一种包管理器. 主要应用在 Fedora, RedHat, Centos等发行版上.
; 查找软件包
通过 yum list 命令可以罗列出当前一共有哪些软件包. 由于包的数目可能非常之多, 这里我们需要使用 grep 命令只筛选出我们关注的包. 例如:
yum list | grep lrzsz
结果如下:
lrzsz.x86_64 0.12.20-36.el7 @base
-
软件包名称: 主版本号.次版本号.源程序发行号-软件包的发行号.主机平台.cpu架构.
-
"x86_64" 后缀表示64位系统的安装包, "i686" 后缀表示32位系统安装包. 选择包时要和系统匹配.
-
"el7" 表示操作系统发行版的版本. "el7" 表示的是 centos7/redhat7. "el6" 表示 centos6/redhat6.
- 最后一列, base 表示的是 "软件源" 的名称, 类似于 "小米应用商店", "华为应用商店" 这样的概念.
补充:
- yum工具在每次安装指定软件包的时候,都会检测源服务器上的软件包信息,为了便捷不用每次都去搜索软件包信息,因此使用 yum makecache 将软件包信息缓存到本地,使用 yum clean all 清理老旧的缓存信息
- yum search 命令:搜索包含指定关键字的软件包
- yum -y update:升级所有包同时,也升级软件和系统内核; yum -y upgrade:只升级所有包,不升级软件和系统内核,软件和内核保持原样
安装与卸载软件包
sudo yum install -y lrzsz
sudo yum remove lrzsz
yum 会自动找到都有哪些软件包需要下载, 这时候敲 "y" 确认安装。出现 "complete" 字样, 说明安装完成.
注意事项:
-
安装软件时由于需要向系统目录中写入内容, 一般需要 sudo 或者切到 root 账户下才能完成.
-
yum 安装软件只能一个装完了再装另一个. 正在 yum 安装一个软件的过程中, 如果再尝试用 yum 安装另外一个软件, yum会报错.
-
如果 yum 报错, 请自行百度.
拓: lrzsz简介
rz,sz 是 Linux/Unix 同 Windows 进行 ZModem 文件传输的命令行工具。
rz 可以很方便的从客户端传文件到服务器,sz 也可以很方便的从服务器传文件到客户端,就算中间隔着跳板机也不影响。
rz :(receive Zmodem)
sz :(send Zmodem)
远程文件传输的工具有很多,例如 rz、sz、scp、sftp、ftp等。
如果环境服务器需要通过跳板机(relay)访问,使用 rz、sz 传输更为方便。
在 SecureCRT 下的传输协议有 ASCII、Xmodem、Ymodem、Zmodem 4种:
- ASCII:这是最快的传输协议,但只能传送文本文件
- Xmodem:这种古老的传输协议速度较慢,但由于使用了CRC错误侦测方法,传输的准确率可高达99.6%
- Ymodem:这是Xmodem的改良版,使用了1024位区段传送,速度比Xmodem要快。
- Zmodem:Zmodem采用了串流式(streaming)传输方式,传输速度较快,而且还具有自动改变区段大小和断点续传、快速错误侦测等功能,是目前最流行的文件传输协议
lrzsz 的使用(需要提前用 yum 安装)
功能:这个工具用于 windows 机器和远端的 Linux 机器通过 XShell 传输文件
- 从 Windows 传到 Linux :
- 使用 rz [ 选项 ] 具体选项可以使用 rz -h 进行查阅
rz -e
- 直接将要上传到 linux 中的文件拖到 xshell 的界面。(小技巧)
- 从 Linux 到 Windows: 使用 sz [ 选项 ] 文件名
sz t1.txt
拓:配置 yum 源路径的方法
yum 的配置文件:/etc/yum.conf,(了解即可)
[liren@VM-8-2-centos tmp]$ ls /etc/yum.conf
/etc/yum.conf
[liren@VM-8-2-centos tmp]$ vim /etc/yum.conf
yum 源的存放地点:/etc/yum.repos.d
若进入到 CentOS-Base.repo 中:
[liren@VM-8-2-centos tmp]$ vim /etc/yum.repos.d/CentOS-Base.repo
若无这些配置,可到百度查找: centos7 配置国内yum源, 进行配置。
Linux开发工具
Linux编辑器-vim使用
vi/vim的区别简单点来说,它们都是多模式编辑器,不同的是vim是vi的升级版本,它不仅兼容vi的所有指令,而且还有一些新的特性在里面。例如语法加亮,可视化操作不仅可以在终端运行,也可以运行于x window、 mac os、windows。我们课堂上,统一按照vim来进行讲解。
; 1、 vim 的基本概念
- 正常/普通/ 命令模式(Normal mode)
控制屏幕光标的移动,字符、字或行的删除,移动复制某区段及进入Insert mode下,或者到 last line mode
- 插入模式(Insert mode)
只有在Insert mode下,才可以做文字输入, 按「ESC」键可回到命令行模式。该模式是我们后面用的最频繁的编辑模式。
- 末行模式(last line mode)
文件保存或退出,也可以进行文件替换,找字符串,列出行号等操作。 在命令模式下, shift + : 即可进入该模式。要查看你的所有模式:打开vim,底行模式直接输入 --> :help vim-modes
还有其他多种,笔记会不断填补...
2. vim 的基本操作
三种常见模式的转换:
进入 vim 的方法:
-
vim + 文件名*
退出 vim 的方法:** -
:w (保存当前文件)
- :wq (输入「wq」,存盘并退出vim)
- :q! (输入q!,不存盘强制退出vim)
; 3、vim 命令模式的操作指令
- *切换为插入模式
- 按「i」 切换进入插入模式「insert mode」,按 "i" 进入插入模式后是从光标当前位置开始输入文件;
- 按「a」 进入插入模式后,是从目前光标所在位置的下一个位置开始输入文字;
-
按「o」 进入插入模式后,是插入新的一行,从行首开始输入文字。
-
从插入模式切换为命令模式
- 按 「Esc」键。
- 移动光标
- vim可以直接用键盘上的光标来 上下左右移动,但正规的vim是用小写英文字母「h」、「j」、「k」、「l」,分别控制光标左、下、上、右移一格
- 按[gg]: 进入到 文本开头
- 按「G」或 「shift + g」或「 n + shift + g」: 移动到 文本末端 或 向下移动n位
- 按「shift + ^」: 移动到 光标所在行的"行首"
- 按「 shift + $ 」: 移动到 光标所在行的"行尾"
- 按「w」: 光标 跳到下个字的开头
- 按「e」: 光标 跳到下个字的字尾
- 按「b」: 光标 回到上个字的开头
- 按「n + 方向键」: 光标 移到该行或上下的第 n 个位置,如:5l,56j
- 按「ctrl」+「b」: 屏幕往"后"移动一页
- 按「ctrl」+「f」: 屏幕往"前"移动一页
- 按「ctrl」+「u」: 屏幕往"后"移动半页
- 按「ctrl」+「d」: 屏幕往"前"移动半页
- 删除文字
- 「x」: 每按一次, 删除光标所在位置的一个字符
- 「n + x」: 例如,「6x」表示 删除光标所在位置的"后面(包含自己在内)"6个字符
- 「X」: 大写的X, 每按一次,删除光标所在位置的"前面"一个字符
- 「n + X」: 例如,「20X」表示 删除光标所在位置的"前面"20个字符
- 「dd」: 删除光标所在行
- 「n + dd」: 从光标所在行开始删除 n 行
- 「dd + p」或「n + dd + p」: 剪切某行 或 剪切n行
- 撤销上一次操作
- 「u」: 如果您误执行一个命令,可以马上按下「u」,回到上一个操作。 按多次"u"可以执行多次回复。
- 「ctrl + r」: 撤销上一次的撤销
- 复制
- 「p」: 将缓冲区内的字符 粘贴到光标所在位置。注意: 所有与"y"有关的复制命令都必须与"p"配合才能完成复制与粘贴功能。
- 「yy」: 复制光标所在行 到缓冲区。
- 「n + yy」: 例如,「6yy」表示拷贝 从光标所在的该行"往下数"6行文字。
- 「yw」: 将 光标所在之处到字尾的 字符 复制到缓冲区中。
- 「n + yw」: 复制 == n 个完整的字符串==到缓冲区
- 替换;更改;切换大小写
- 「shift + ~」: 将 光标处的大小写互相切换
- 「r」: 替换光标所在处的字符。
- 「n + r」: 替换光标所在处的 n 个字符。
- 「shift + r ®」: 切换为 替换模式,直到按下「ESC」键为止。
- 「cw」: 更改 光标所在处的字到字尾处
- 「c + n + w」: 例如,「c3w」 *表示更改3个完整的字符串
4、vim 底行模式的操作命令
在使用末行模式之前,请记住先按「ESC」键确定您已经处于正常模式,再按「:」冒号即可进入末行模式。
- 行号
- 「set nu」: 输入「set nu」后,会在文件中的每一行前面列出行号。
- 「set nonu」: 取消行号。
- 跳到文件中的某一行
- 「#」:「#」号表示一个数字,在冒号后输入一个数字,再按回车键就会跳到该行了,如输入数字15,再回车,就会跳到文章的第15行。
- *查找字符
- 「/ + 关键字」: 先按「/」键,再输入想寻找的字符,如果第一次找的关键字不是您想要的,可以一直按「n」会往后寻找到您要的关键字为止。
- 「? + 关键字」: 先按「?」键,再输入想寻找的字符,如果第一次找的关键字不是您想要的,可以一直 按「n」会往前寻找到您要的关键字为止。
-
问题:/ 和 ?查找有和区别? 由操作可知,两者差别为:「/ + 关键字」查找第二个的时候是从上到下找 的,而「? + 关键字」是从下往上找的
-
保存文件 与 退出vim
- 「w」: 在冒号输入字母「w」就可以将文件保存起来
- 「q」: 按「q」就是退出,如果无法离开vim,可以在「q」后跟一个「!」强制离开vim。
- 「wq」: 一般建议离开时,搭配「w」一起使用,这样在退出的时候还可以保存文件。
- 「x!」: 保存并退出编辑, 仅当文件有修改时会保存,并修改文件时间属性
- 不退出 vim 执行命令行命令
- 「:! + 命令」: 如 「 :! gcc test.c」 即可在vim中编译.c文件
- 在 vim 中的分屏
- 「: vs + 文件名」: 如在 test.c 中 打开或创建一个文件「 : vs liren.c 」
- 「ctrl + w」: 光标在分屏的 *多屏幕下进行切换
简单的 vim 配置
配置文件的位置
- 在 目录 /etc/ 下面,有个 名为 vimrc 的文件,这是 系统中公共的vim配置文件,对所有用户都有效。
- 而在每个用户的主目录下,都可以自己建立私有的配置文件,命名为: ".vimrc"。例如,/roo t目录下,通常已经存在一个.vimrc文件, 如果不存在,则创建之。
- 切换用户成为自己执行 su ,进入自己的主工作目录,执行 cd ~
- 打开自己目录下的 .vimrc 文件,执行 *vim .vimrc
注:直接到百度查找vim配置项,做为了解即可。 —> 一套完整的配置文件(直接安装即可)
参考资料
Linux编译器-gcc/g++使用
gcc 与 g++ 的安装
- 对于 gcc
sudo yum install gcc
- 对于 g++ 与 gcc 不同,直接 install g++是找不到,要查找 gcc-c++
sudo yum install gcc-c++
1、 背景知识
- 预处理(宏定义,文件包含,条件编译,去注释等)
- 编译(生成汇编)
- 汇编(生成机器可识别代码)
- 连接(生成可执行文件或库文件)
2、gcc如何完成
- 格式: *gcc [选项] 要编译的文件 [选项] [目标文件]
预处理 (进行宏替换) (-E)(生成 .i)
- 预处理功能主要 包括 宏定义,文件包含,条件编译,去注释等。
- 预处理指令是 以 # 号开头的代码行。
- 实例: gcc –E hello.c –o hello.i (-o hello.i 也可以放到前面去,只要 -o后面接着的是.i文件即可)
- 选项 "-E" , 该选项的作用是让 gcc 在预处理结束后停止编译过程。
- 选项 "-o" *是指目标文件,".i" 文件为已经过预处理的C原始程序。
编译(生成汇编) (-S)(生成 .s)
- 编译过程为 :扫描程序–>语法分析–>语义分析–>源代码优化–>代码生成器–>目标代码优化
- 扫描程序进行词法分析,从左向右,从上往下扫描源程序字符,识别出各个单词,确定单词类型
- 语法分析是根据语法规则,将输入的语句构建出分析树,或者语法树,也就是我们提到的分析树parse tree或者语法树syntax tree
- 语义分析是根据上下文分析函数返回值类型是否对应这种语义检测,可以理解语法分析就是描述一个句子主宾谓是否符合规则,而语义用于检测句子的意思是否是正确的
- 在这个阶段中,gcc 首先要 检查代码的规范性、是否有语法错误等,以确定代码的实际要做的工作,在检查无误后,gcc 把代码翻译成汇编语言。
- 用户可以使用 "-S" 选项来进行查看,该选项 只进行编译而不进行汇编,生成汇编代码, 生成的后缀文件为 .s
- 实例: *gcc –S hello.i –o hello.s
汇编(生成机器可识别代码) (-c)(生成 .o)
- 汇编阶段是 把编译阶段生成的 ".s" 文件转成目标文件
- 可使用选项 "-c" 就可看到 汇编代码已转化为 ".o" 的二进制目标代码(目标代码生成指的是,把中间代码变换成为特定机器上的低级语言代码)了
- 实例: gcc –c hello.s –o hello.o
- 目标文件也称为可重定向目标文件,该文件不可被执行,还得经过链接才能完成重定向。
链接(生成可执行文件或库文件) (生成可执行文件,在 Linux中为 .out)
- 在 成功编译之后,就进入了链接阶段。
- 实例: *gcc hello.o –o hello
在这里涉及到一个重要的概念 : 函数库
-
我们的C程序中,并没有定义"printf"的函数实现,且在预编译中包含的"stdio.h"中也只有该函数的声明,而没有定义函数的实现,那么,是在哪里实"printf"函数的呢?
-
最后的答案是: 系统把这些函数实现都被做到名为 libc.so.6 的库文件中去了,在没有特别指定时,gcc 会到系统默认的搜索路径 "/usr/lib" 下进行查找,也就是链接到 libc.so.6 库函数中去,这样就能实现函数 "printf" 了,而这也就是链接的作用。
函数库一般分为静态库和动态库两种 (详细解释可到笔记中去查阅)
- 静态库是指 编译链接时,把库文件的代码全部加入到可执行文件中,因此 生成的文件比较大,但在 运行时也就不再需要库文件了。其后缀名一般为 ".a"
- 动态库与之相反,在编译链接时并没有把库文件的代码加入到可执行文件中, 而是在程序执行时由运行时链接文件加载库,这样可以节省系统的开销。动态库一般后缀名为 ".so",如前面所述的 libc.so.6 就是动态库。 gcc 在编译时默认使用动态库。完成了链接之后,gcc 就可以生成可执行文件,如下所示。 gcc hello.o –o hello
; 🐛 附加
默认系统会自动携带动态库,而不存在静态库,如果我们需要使用静态库链接的话,需要自己手动安装
- 对于c:sudo yum install -y glibc-static
- 对于c++:sudo yum install -y libstdc+±static
3、gcc 选项
- -E: 只激活预处理,这个不生成文件,你需要把它重定向到一个输出文件里面
- -S: 编译到汇编语言不进行汇编和链接
- -c: 编译到目标代码
- -o: 文件输出到 文件
- -D: 宏的命令行定义,多用于 条件编译中的调试
- -static: 此选项 对生成的文件采用静态链接
- -g: 生成debug程序。GNU 调试器可利用该信息。
- -std=c99 或 -std=gnu99:用c99或其他标准(或c++11等等)来生成可执行文件
-
-shared: 此选项将尽量使用动态库,所以生成文件比较小,但是 需要系统有动态库.
-
-O0: 编译器的优化选项的4个级别,-O0表示没有优化,-O1为缺省值,-O3优化级别最高
- -O1
- -O2
- -O3
- -w: 不生成任何警告信息。
- -Wall: 生成所有警告信息。
Linux调试器-gdb使用
1. 、 背景
- 程序的 发布方式有两种, debug模式和 release模式
- Linux gcc/g++出来的二进制程序,默认是release模式
- 要使用gdb调试, *必须在源代码生成二进制程序的时候, 加上 -g 选项
2、怎么查看文件是否可以 debug
用下面的命令即可,如果可以debug,则会显示debug相关的一些信息,否则没有相关信息。
objdump --syms your-binary | grep debug 或 objdump -t your-binary | grep debug
[liren@VM-8-2-centos tmp1]$ objdump --syms mytmp | grep debug
0000000000000000 l d .debug_aranges 0000000000000000 .debug_aranges
0000000000000000 l d .debug_info 0000000000000000 .debug_info
0000000000000000 l d .debug_abbrev 0000000000000000 .debug_abbrev
0000000000000000 l d .debug_line 0000000000000000 .debug_line
0000000000000000 l d .debug_str 0000000000000000 .debug_str
3、gdb 的使用
gdb binFile 退出: ctrl + d 或 quit 调试命令:
- (list 或者 l)+ 行号: 显示binFile源代码, 接着上次的位置往下列 , 每次列10行
- (list 或者 l)+ 函数名: 列出某个 函数的源代码
- r 或 run: 运行程序,从开始连续而非单步执行程序
- n 或 next: 单条执行,逐过程
- s 或 step: 进入函数调用,逐语句
- c(continue): 直接跳转到下一个断点
- until X行号: 跳至X行
- finish: 直接运行完毕对应的函数
- b(break) + 行号: 在 某一行设置断点
- b(break) + 函数名: 在 某个函数开头设置断点
- i(info) b(break) : 查看断点信息
- d(delete) b(breakpoints): 删除所有断点
- d(delete) b(breakpoints) + 行号: 删除序号为 n 的断点
- disable b(breakpoints): 禁用断点
- enable b(breakpoints): 启用断点
- p(print) + 变量或表达式: 打印表达式的值,通过表达式可以修改变量的值或者调用函数
- display 变量名: 跟踪查看一个变量,每次停下来都显示它的值,==相当于vs中的监视 ==*
- undisplay 变量名: 取消对先前设置的那些变量的跟踪
- bt(breaktrace): 查看各级函数调用及参数,相当于vs中的调用堆栈窗口
- i(info) locals: 查看当前栈帧局部变量的值
- set 变量名=n: *修改变量的值为 n
Linux项目自动化构建工具-make/Makefile
背景
- 会不会写makefile,从一个侧面说明了一个人是否具备完成大型工程的能力
- 一个工程中的源文件不计数,其按类型、功能、模块分别放在若干个目录中,makefile定义了一系列的规则来指定,哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译,甚至于进行更复杂的功能操作
- makefile带来的好处就是——"自动化编译",一旦写好,只需要一个make命令,整个工程完全自动编译,极大的提高了软件开发的效率。
- make是一个命令工具, 是一个解释makefile中指令的命令工具,一般来说,大多数的IDE都有这个命令,比如:Delphi的make,Visual C++的nmake,Linux下GNU的make。可见,makefile都成为了一种在工程方面的编译方法。
- make是一条命令,makefile是一个文件,两个搭配使用,完成项目自动化构建。
实例:
mytmp:tmp.c
gcc -o tmp.c tmp.c
.PHONY:clean
clean:
rm -f mytmp
依赖关系:
如果是以这个为例子的话,其中:
- mytmp 依赖于 tmp.o
- tmp.o 依赖于 tmp.s
- tmp.s 依赖于 tmp.i
- tmp.i 依赖于 tmp.c*
这样子相当于上面例子的mytmp 依赖于 tmp.c, 而我们一般操作时候也以 mytmp 依赖于 tmp.c 为主,更加简洁**
; 依赖方法:
上面例子中的 gcc -o mytmp tmp.c 就是依赖方法
原理
make 是如何工作的,在默认的方式下,也就是我们 只输入 make 命令。那么,
- make 会在 当前目录下找名字叫 "Makefile" 或 "makefile" 的文件。
- 如果找到,它会找文件中的第一个目标文件(target),在上面的例子中,他会找到 "mytmp" 这个文件, 并把这个文件作为最终的目标文件。
- 如果 mytmp文件不存在,或是 mytmp 所依赖的后面的 tmp.o 文件的 文件修改时间要比 mytmp 这个文件新(可以用 touch 测试),那么, 他就会执行后面所定义的命令来生成 mytmp 这个文件。
- 如果 mytmp 所依赖的 tmp.o 文件不存在,那么 make 会在 当前文件中找目标为 tmp.o文件的依赖性, 如果找到则再根据那一个规则生成 tmp.o 文件。(这有点像一个堆栈的过程)
- 当然,你的 .c文件和 .h文件是存在的啦,于是 make 会生成 tmp.o 文件, 然后再用 tmp.o 文件声明 make 的终极任务,也就是执行文件 mytmp 了。
- 这就是整个 make 的依赖性, make 会一层又一层地去找文件的依赖关系,直到最终编译出第一个目标文件。
- 在找寻的过程中, 如果出现错误,比如最后被依赖的文件找不到,那么 make 就会直接退出,并报错,而对于所定义的命令的错误,或是编译不成功,make根本不理。
- make 只管文件的依赖性,即, 如果在我找了依赖关系之后,冒号后面的文件还是不在,那么对不起,我就不工作啦。
项目清理
- 工程是需要被清理的
- 像 clean 这种,没有被第一个目标文件直接或间接关联,那么它后面所定义的命令将不会被自动执行,不过,我们可以显示要 make 执行。即命令——"make clean",以此来清除所有的目标文件,以便重编译。
- 但是 一般我们这种 clean 的目标文件,我们将它设置为伪目标,用 .PHONY 修饰,伪目标的特性是,总是被执行的*。
; 补充:几个实用的符号
- $@:表示依赖关系中的目标文件
- $^ :表示依赖关系中的依赖文件列表
- *$< :表示依赖关系中的一个一个的依赖文件
举例:
mytest:test.o main.o
gcc -o $@ $^
test.o:test.c
gcc -c $<
main.o:main.c
gcc -c $<
.PHONY:clean
clean:
rm -f *.o mytest
补充的知识点:
- makefile文件中,保存了编译器和链接器的参数选项,并且描述了所有源文件之间的关系。make程序会读取makefile文件中的数据,然后根据规则调用编译器,汇编器,链接器产生最后的输出,即 makefile文件保存了编译器和连接器的参数选项。
- Makefile里主要包含了五个东西: 显式规则、隐晦规则、变量定义、文件指示和注释
- 显式规则说明了,如何生成一个或多个目标文件。
- make有自动推导的功能,所以隐晦的规则可以让我们比较粗糙地简略地书写makefile,比如源文件与目标文件之间的时间关系判断之类
- 在makefile中可以定义变量,当makefile被执行时,其中的变量都会被扩展到相应的引用位置上,通常使用 $(var) 表示引用变量
- 文件指示。包含在一个makefile中引用另一个makefile,类似C语言中的include。
- 注释,makefile中可以使用 # 在行首表示行注释
- 默认的情况下,make命令会在当前目录下按顺序找寻文件名为"GNUmakefile"、"makefile"、"Makefile"的文件
- make的执行规则是,只生成所有目标对象中的第一个,当然make会根据语法规则,递归生成第一个目标对象的所有依赖对象后再回头生成第一个目标对象,生成后退出。
- make在执行makefile规则中,根据语法规则,会分析目标对象与依赖对象的时间信息,判断是否在上一次生成后, 源文件发生了修改,若发生了修改才需要重新生成。
- makefile中的伪对象表示对象名称并不代表真正的文件名,与实际存在的同名文件没有相互关系,因此伪对象不管同名目标文件是否存在都会执行对应的生成指令。 伪对象的作用有两个,1. 使目标对象无论如何都要重新生成。2. 并不生成目标文件,而是为了执行一些指令。
🔴 一个问题:为什么如果源文件没有修改,make 后不会产生新的可执行文件呢?怎么证明?
首先我们得先了解一个东西,就是文件的一些时间问题:
一个文件的时间分为三种: Access、Modify、Change,这三种分别有什么区别呢?
Access: 表示最后一次访问(不包括改动)文件的时间,当时新版本中优化了,为了减少频繁的改变时间带来的负载,新版本将其设为 多次访问后才会修改 Access 的时间,而不是一次!
Modify: 表示该 文件内容 被修改的时间
Change: 表示该 文件属性 被修改的时间(其实也 包括文件权限,大小,属性等等,因为改变了内容就改变了文件大小,文件属性也就跟着改变了)
把上面的文件时间搞明白之后,我们想一想,一个文件是否需要被重新生成,是不是与其改变的时间有关?
答案是对的!与其 Modify 即修改时间是有关系的,如果源文件没有被改动,其 make 后的可执行文件的 Modify 时间应当是和源文件相同的,所以系统会去比较这两个时间,相同则说明不需要重新生成;若源文件被改动了,那么源文件的 Modify 时间肯定是要比原来 make 的可执行文件要新,所以重新 make 的话,系统去比较时间的时候就会判断源文件被改动了,所以就会重新生成可执行文件!
下面我们用 touch 指令来验证一下:( touch 一个存在的文件,其修改时间是会被改变的~)
; Linux 第一个小程序-进度条与倒计时
行缓冲区概念 (具体的后面 I/O 部分还详细的讲解)
- 行缓冲:输入或输出缓冲区== 遇到 换行符(\n)==会进行实际 I/O 操作
- 行刷新:显示器默认 遇到 换行符(\n) 会将行缓冲区的内容显示出来
- 其中显示器默认的刷新方式是行刷新*
若不想被缓冲,得用 fflush()** 函数继续刷新
\r 与 \n 的区别
- \n : 换到下一行,称为 换行
- \r : 代表的是光标回到 当前行 的最开始的位置 ,称为 *回车
注:根据上面的概念,真正的回车符号应该是 \r ,即回到当前行的起始位置,而我们通常了解的 \n 应该是回车换行符,因为它的功能既包括了回车,也包括了换行,即光标跳转到下一行的起始位置。
所以我们可以用 \r 来进行倒计时功能的实现:
void Count()
{
int i = 15;
while(i)
{
printf("%-2d\r", i);
fflush(stdout);
sleep(1);
i--;
}
}
进度条代码:
```c
proc.h
include "proc.h"
char style[Max] = {'>','+','$','~','#'};
void ProcBar()
{
int i = 0;
char proc[102] = {0};
const char* tmp = "|/-\";
while(i 100)
{
printf("[%-100s][%d%%][%c]\r", proc, i, tmp[i%4]);
fflush(stdout);
proc[i++] = style[N];
usleep(50000);
}
printf("\n");
}
makefile
Original: https://blog.csdn.net/lirendada/article/details/127822834
Author: 利刃Cc
Title: Linux环境基础开发工具