【命令行魔法:掌握Linux基础工具开发的独门技艺】(四)

简介: 【命令行魔法:掌握Linux基础工具开发的独门技艺】

【命令行魔法:掌握Linux基础工具开发的独门技艺】(三):https://developer.aliyun.com/article/1425542


4.3原理


  • make是如何工作的,在默认的方式下,也就是我们只输入make命令。那么


1. make会在当前目录下找名字叫“Makefile”或“makefile”的文件。


2. 如果找到,它会找文件中的第一个目标文件(target),在上面的例子中,他会找到“mybin”这个文件, 并把这个文件作为最终的目标文件。


3. 如果mybin文件不存在,或是mybin所依赖的后面的test.o文件的文件修改时间要比mybin这个文件新(可以用 touch 测试),那么,他就会执行后面所定义的命令来生成mybin这个文件。


4. 如果mybin所依赖的test.o文件不存在,那么make会在当前文件中找目标为test.o文件的依赖性,如果找到则再根据那一个规则生成test.o文件。(这有点像一个堆栈的过程)


5. 当然,你的C文件和H文件是存在的啦,于是make会生成 test.o 文件,然后再用 test.o 文件声明 make的终极任务,也就是执行文件mybin了。


6. 这就是整个make的依赖性,make会一层又一层地去找文件的依赖关系,直到最终编译出第一个目标文件。


7. 在找寻的过程中,如果出现错误,比如最后被依赖的文件找不到,那么make就会直接退出,并报错, 而对于所定义的命令的错误,或是编译不成功,make根本不理。


8. make只管文件的依赖性,即,如果在我找了依赖关系之后,冒号后面的文件还是不在,那么对不起, 我就不工作啦。


4.4项目清理


  • 工程是需要被清理的
  • 像clean这种,没有被第一个目标文件直接或间接关联,那么它后面所定义的命令将不会被自动执行, 不过,我们可以显示要make执行。即命令——“make clean”,以此来清除所有的目标文件,以便重编译。
  • 但是一般我们这种clean的目标文件,我们将它设置为伪目标,用 .PHONY 修饰,伪目标的特性是,总是被执行的。
  • 可以将我们的 hello 目标文件声明成伪目标,测试一下。


怎么清理呢?vim打开Makefile        


即命令——“make clean”,以此来清除所有的目标文件,以便重编译。


我们再来改一下vim里面的顺序


1.Makefile和make形成目标文件的时候,默认是从上到下扫描makefile文件的,默认形成的是第一个目标文件。

2.有多个依赖关系和依赖方法,默认只形成一个。


5.Linux第一个小程序-进度条


5.1.缓冲区概念


首先我们将makefile和源文件搭建好


然后我们验证一下我们写的是否有问题


然后我们验证两个代码,观看它们的现象。

#include <stdio.h>
int main()
{
    printf("hello Makefile!\n");
    sleep(3);
    return 0;
}


我们可以发现上面代码的运行结果是先输出printf,然后等待三秒


#include <stdio.h>
int main()
{
    printf("hello Makefile!");
    sleep(3);
    return 0;
}


我们发现上代码的运行结果是先等待三秒,然后再输出printf


但是我们不要被上面的现象所迷惑,C语言代码是遵守顺序结构的,所以我们可以知道上面的代码永远是先执行printf("hello Makefile!");然后在执行sleep(3);但是为什么会出现上面的想象呢?


这是因为我们的C语言有一个缓冲区,当sleep没有执行完的时候,printf的字符串被保存到缓冲区了,当sleep执行完的时候,此时就要求刷新缓冲区,于是此时才输出printf语句,而第一个代码直接输出是因为'\n'字符会立刻刷新缓冲区,于是就先输出了printf语句。

#include <stdio.h>
int main()
{
    printf("hello Makefile!");
    fflush(stdout);
    sleep(3);
    return 0;
}


我们可以通过手动刷新缓冲区,先输出printf内容。


5.2.\n:换行符与\r:回车符之间的区别



所以准备工作已经完成了,现在开始写我们的进度条小程序。


5.3.进度条代码



但是此时我们发现make编译后运行我们的程序没有任何结果


因为我们上面的printf内容被保存到缓存区了,所以没有输出我们想要的结果,所以我们就要使用fflush进行强制刷新缓冲区。


然后我们再运行我们的代码。


这样就实现了我们的倒计时小程序,不过我们上面只能从9倒计时,如果我们想从10倒计时呢?


我们发现我们的程序不能完成从10倒计时,输出的时候后面多了一个0,为什么呢?


当我们向显示器打印10的时候,打印的是字符'1'和'0',当我们后面打印的时候,字符只依次覆盖'1'字符,并没有覆盖'0'字符。怎么解决呢?-2d:表示输出这个整数的时候预留两个字符的空间并左对齐输出这个整数


输出结果:


现在我们就来写一下我们的进度体条小程序,首先学习一下usleep函数,按照微秒的时间进行休眠。


我们先来建立一下多个文件并写上一个简单的打印输出工作


然后我们先验证一下make能否编译


接下来就可以写我们的进度条了。


我们的程序输出的进度条主要在processbar.c中实现的,字符数组设置为102是因为在我们的程序中,循环共循环了101次,bar[100]='#',如果设置数组大小101,此时下标最大就是100,而100下标处存放了bar[100]='#',没有位置存放'\0',这样程字符串就没有结束的标识,程序就达不到预期的结果。这里要注意最后一次,下标的位置是bar[100]='#',那从0开始到100不就有101个'#'符号吧吗?并不是,我们自己看我们的程序,当下标为0的时候,我们的程序时不打印'#'的,下标为1的时候才打印'#'的。

#include <iostream>
using namespace std;
int main()
{
  int cnt = 0;
  char bar[5];
  memset(bar, '\0', sizeof(bar));
  while (cnt <= 3)//下标为0,1,2,3
  {
    printf("[%s]", bar);
    bar[cnt++] = '#';
  }
  return 0;
}

运行结果:


所以此时小程序下标就是100,即可输出100个字符'#",结果运行:


但是我们平常的进度条不是#,我们期待能出现一个箭头的形式,我们可以在0下标处设置为字符'<',后续用字符'='覆盖前面的字符'<',我们来看一下程序的运行结果:


我们发现上面的程序输出了101个字符,我们期待最后一个字符应该是'=',我们来看一下我们的程序,当i=100的时候,此时bar[100]='>',循环再次进入的时候,最后一个元素输出是'>',然后i++,bar[100]位置被修改为'=',然后i++变为101,此时不再进入循环,虽然bar[100]位置被修改为'=',但是此时没有执行打印输出工作,所以最后一个仍然是'>'字符。

#include <iostream>
using namespace std;
int main()
{
  int cnt = 0;
  char bar[6];
  memset(bar, '\0', sizeof(bar));
  bar[0] = '>';
  while (cnt <= 3)//下标是0,1,2,3
  {
    printf("[%s]", bar);
    bar[cnt++] = '=';
    if (cnt <= 3)
      bar[cnt] = '>';
  }
  return 0;
}

运行结果:


监视窗口可以看到bar最后一个元素是'=',只不过输出的时候没有打印出来。


因此我们可以修改一下我们的程序,当i<100的时候就不要再执行修改'>'了。


但是实际上进度条并不是一个独立的程序,而是依附于其他应用的,比如我们下载一个文件就要进度条,进度条应该表现为下载量除以文件大小。接下来我们模拟一个下载的场景。


运行结果:


因此我们可以改善一下进度条。


上面的程序我们使用了我们的函数指针,通过回调函数可以调用函数,并且我们修改旋转光标不和rate进度条相关,并且给printf输出加上颜色打印,使我们的进度条更加美观。


进度条:

相关文章
|
11月前
|
安全 Linux Shell
四、Linux核心工具:Vim, 文件链接与SSH
要想在Linux世界里游刃有余,光会“走路”还不够,还得配上几样“高级装备”。首先是Vim编辑器,它像一把瑞士军刀,让你能在命令行里高效地修改文件。然后要懂“软硬链接”,软链接像个快捷方式,硬链接则是给文件起了个别名。最后,SSH是你的“传送门”,不仅能让你安全地远程登录服务器,还能用scp轻松传输文件,设置好密钥更能实现免-密登录,极大提升效率。
666 5
|
11月前
|
Unix Linux 程序员
Linux文本搜索工具grep命令使用指南
以上就是对Linux环境下强大工具 `grep` 的基础到进阶功能介绍。它不仅能够执行简单文字查询任务还能够处理复杂文字处理任务,并且支持强大而灵活地正则表达规范来增加查询精度与效率。无论您是程序员、数据分析师还是系统管理员,在日常工作中熟练运用该命令都将极大提升您处理和分析数据效率。
890 16
|
11月前
|
安全 Linux iOS开发
SonarQube Server 2025 Release 5 (macOS, Linux, Windows) - 代码质量、安全与静态分析工具
SonarQube Server 2025 Release 5 (macOS, Linux, Windows) - 代码质量、安全与静态分析工具
436 0
SonarQube Server 2025 Release 5 (macOS, Linux, Windows) - 代码质量、安全与静态分析工具
|
缓存 监控 Linux
Linux系统性能调优技巧和相关工具
Linux 作为一种应用应展和系统服务的优选操作系统,在处理性能和端到端点评估上持有出色表现。但是,在处理进程或系统处于低效状态时,性能调优就显得十分重要。本文将探讨一些 Linux 系统性能调优的常用技巧,并介绍相关工具
346 1
Linux系统性能调优技巧和相关工具
|
Linux 数据安全/隐私保护 iOS开发
推荐Linux环境下效能优良的双向文件同步工具
综合上述条件,对于Linux环境下的双向文件同步需求,Unison 和 Syncthing 是两个非常出色的选择。它们都有良好的社区支持和文档资源,适用于不同规模的环境,从个人使用到商业部署。Unison 特别适合那些需要手动干预同步过程、需要处理文件冲突解决的场景。而 Syncthing 更加现代化,适合需要自动、实时的数据同步与备份的环境。对于选择哪一个,这将取决于个人的使用场景和具体需求。
1398 16
|
Ubuntu 搜索推荐 Linux
详解Ubuntu的strings与grep命令:Linux开发的实用工具。
这就是Ubuntu中的strings和grep命令,透明且强大。我希望你喜欢这个神奇的世界,并能在你的Linux开发旅程上,通过它们找到你的方向。记住,你的电脑是你的舞台,在上面你可以做任何你想做的事,只要你敢于尝试。
630 32
|
数据采集 编解码 运维
一文讲完说懂 WowKey -- WowKey 是一款 Linux 类设备的命令行(CLT)运维工具
WowKey 是一款面向 Linux 类设备的命令行运维工具,支持自动登录、批量执行及标准化维护,适用于企业、团队或个人管理多台设备,显著提升运维效率与质量。
|
Linux 数据安全/隐私保护
使用Linux命令行接入无线网络Wi-Fi的示例。
现在,你已经使用命令行成功地连接到 Wi-Fi 网络了。这两个示例涵盖了用 `nmcli` 和 `wpa_supplicant` 连接无线网络的常见场景,让你能够不依赖图形化界面来完成这个任务。在日常使用中熟练掌握这些基本操作能增强你对 Linux 系统的理解,帮助你更有效地处理各种问题。
1226 12
|
Java Linux 开发工具
Linux下版本控制器(SVN) -命令行客户端
Linux下版本控制器(SVN) -命令行客户端
479 4