【Linux详解】进度条实现 Linux下git 的远程上传
📃个人主页:island1314
🔥个人专栏:Linux—登神长阶
⛺️ 欢迎关注:👍点赞 👂🏽留言 😍收藏 💞 💞 💞
🚀前言
💢在实现进度条之前,我们先来了解一下换行和回车,以及缓冲区的概念,以便于我们来实现进度条,注:我们还需要用到上篇文章的知识:【Linux必备工具】自动化构建工具makefile的使用详解-CSDN博客
1. 回车与换行
我们在学C语言的时候,发现当我们在一行内容没有写完,然后要换到下一行的开始,我们要进行两个操作,
1:\n(换行)
让光标从第一行跳到第二行,但是光标只是垂直向下跳,并没有在第二行的开始。
2:\r(回车)
在第二行让光标跳到最开始的位置,这个操作就是回车。
那为啥我们在C语言的时候,怎么用\n来换行加回车?
因为这是我们在这个语言环境下我们将其简化,此时的\n就表示回车加换行。
测试字符
我们一共测试四种情况,
- \r和\n都存在
- \r和\n都不存在
- 只有\n
- 只有\r
🍎(1) \r和\n都存在
看下图可发现,我们在其中既有回车又有换行,所以其
linux
的命令行在我们执行程序下面。
🍌(2) \r和\n都不存在
看下图可发现:Linux命令行紧跟着打印的信息,
因为我们结尾啥都没有,那光标就还在结尾,所以Linux命令行紧跟我们的打印信息
🍐(3) 只有\n
这里我们就省略演示了,毕竟这个现象和1相同,就是和我们的换行+回车,和我们平时用的一样,只不过我们的编译器将两步简化为一步了,我们只需要输入\n即可
🍇(4) 只有\r
现象:看不到打印的信息了。只能看到linux命令行
💢解释:因为我们\r
,只有回车的效果,我们本来光标在文本行的最后一个字符旁边,但是我们识别到\r字符,所以,直接回车,光标来到了文本行的开始。这时linux
的命令行就会从光标处开始,将我们的文本覆盖掉,我们就什们都看不到。
2. 缓冲区
2.1 缓冲区概念
💢缓冲区是计算机内存的一部分,用于暂时存储数据。它在数据传输过程中起到一个缓冲桥梁的作用,帮助协调数据传输的速度差异。缓冲区可以是磁盘缓存,网络传输中的数据缓存等。
2.2 缓冲区作用
缓冲区的作用非常广泛和重要,主要体现在以下几个方面:
提升读写效率
- 当进程要进行文件读写操作时,数据会首先存储在缓冲区中,而不是直接写入磁盘。缓冲区根据特定的刷新策略定期或在特定条件下将数据写入磁盘。这样可以减少磁盘的频繁读写动作,从而提升整体系统的效率。
减少等待时间
- 在没有缓冲区的情况下,每次文件读写操作都需要等待外设(如磁盘)就绪,这可能会导致显著的等待时间。缓冲区减少了这种等待时间,因为数据可以暂时存储在内存中,进程可以继续进行其他任务,而无需等待外设操作完成。
我们先来分析下面几段代码感受一下行缓冲区的存在:
在Linux当中以下代码的运行结果是什么样的?
#include <stdio.h>
#include <unistd.h> int main()
{printf("你能看见我嘛\n");sleep(2);return 0;
}
这段代码运行结果显而易见:printf
函数直接先打印内容,然后再休眠2秒。
注:sleep的作用是按秒去休眠,头文件为<unisted.h>
然后当我们去除后面的 '\n' 则会出现什么了
缓存
💢实际上,printf 已经先执行了,只是这个 "Helo,World" 没有立马被显示出来罢了!
当我们 sleep 时也没有显示,当我们 sleep 完甚至到程序退出后,这个 "Helo,World" 才显示出来。
💢说明带有\n会马上刷新,那么不带的时候,那2s 代码就是存在我们的缓冲区, return 退出的时候,这个数据才显示出来,所以才看到了我们现在看到的现象 。
2.3 缓冲区刷新策略
缓冲区的刷新策略决定了何时将缓冲区中的数据真正写入到目标存储器,如磁盘或显示器。主要有以下几种策略:
a、无缓冲(Unbuffered)
数据一写入缓冲区就立即刷新写入目标设备。这种方式适合对时间敏感的操作,但可能导致系统资源的低效利用。
b、行缓冲(Line Buffered)
当缓冲区检测到换行符(\n)时,立即刷新写入目标设备。这种方式常用于终端显示器,以保证一行行的输出效果。例如,在终端或控制台输出时,行缓冲能确保即时显示用户输入的一行内容。
c、全缓冲(Fully Buffered)
只有当缓冲区满了时,才会将数据刷新写入目标设备。这种方式适合大量数据的写入操作,能提高整体的写入效率。例如,在将数据写入磁盘文件时,通常使用全缓冲策略。
d、特殊策略
- 用户强制刷新
用户可以显式调用刷新函数(如fflush(FILE *stream)
)来强制刷新缓冲区内容。- 进程退出刷新
当进程正常退出时,缓冲区会自动刷新,以确保所有已写入缓冲区但尚未写入目标设备的数据都被处理完毕。
如果我们想让上面的hello马上打印,就可以进行如下操作啦
#include <stdio.h>
#include <unistd.h>int main()
{printf("Hello Linux");fflush(stdout); //立刻刷新,直接打印出结果sleep(2);return 0;
}
现在就会打印出1中(2)的那种结果啦
2.4 缓冲区存储位置
💢标准输入输出流(stdin、stdout、stderr)和文件流都是 FILE* 类型,它们在缓冲区管理中扮演了重要角色。当我们打开一个文件时,系统会返回一个 FILE* 类型的指针,文件的读写和关闭操作都需要该指针作为参数。
内部结构
💢struct FILE 封装了文件描述符(fd)、缓冲区以及缓冲区刷新策略。这使得文件操作变得高效和透明,开发者无需关心低级别的文件操作细节。
2.5 总结
💢缓冲区是提高系统数据读写效率的重要机制。理解和有效利用缓冲区及其刷新策略,可以显著提升程序性能和资源利用效率。
3. 进度条的实现
💢我们知道了上面两个知识点,\r将光标回到最开始就可以将其覆盖掉,所以我们利用这个特点可以写一个倒计时小程序,那我们先写一个10秒以内的倒计时小程序,这样方便更好来实现进度条
3.1 倒计时的实现
#include <stdio.h>
#include <unistd.h>int main()
{int cnt=10;while(cnt--)//循环判断的条件{printf("倒计时:%-2d\r",cnt);//输出倒计时的数字, %-2d把两位覆盖,\r刷新数据sleep(1);//间隔一秒fflush(stdout);//刷新缓冲区}printf("\n");//刷新缓冲区,换行 return 0;
}
3.2 进度条样式
- 主体样式为两个中括号包裹,中间
=>
推进的方式呈现,比如:[======]
- 主体右侧中括号位置保持不变,中间元素不断推进,比如:
[= ]
- 显示当前加载进度,用
[num%]
显示,num
随着进度条的不断推进而变化- 显示加载样式,可以利用一个旋转的字符,例如
[\]
的样式,顺时针不断旋转
大约呈现状态为:[========>] [15%] [\]
3.3 采用多文件
文件存放在 processbar 目录中
- process.h :函数声明
- process.c :进度条逻辑
- main.c :函数调用
3.4 代码如下:
🍉版本一:
process.h
#pragma once//进度条函数void Progress();
process.c
#include "process.h"
#include <stdio.h>
#include <unistd.h>
#include <string.h>#define NUM 101
#define STYLE '='void Process()
{const char *lable = "|/-\\";int len = strlen(lable);char bar[NUM];memset(bar, '\0', sizeof(bar));int cnt = 0;while(cnt <= 100){printf("[%-100s][%d%%][%c]\r", bar, cnt, lable[cnt%len]);fflush(stdout);bar[cnt] = STYLE;cnt++;if(cnt == NUM){bar[cnt - 1] = '\0';printf("[%-100s][%d%%][%c]\r", bar, cnt-1, lable[cnt%len]);break;}bar[cnt] = '>';usleep(100000);}printf("\r\n");
}
main.c
#include "process.h"int main()
{process(); return 0;
}
🥝版本二:
process.h
#pragma oncevoid FlushProcess(double total, double current);
process.c
#include "process.h"
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>#define NUM 101
#define STYLE '='
#define POINT '.'
#define SPACE ' 'const int pnum = 6;// 真实的进度条,一个根据具体的情况,比如下载的量来动态刷新进度
void FlushProcess(double total, double current)
{// 1. 更新当前进度的百分比double rate = (current / total) * 100;// printf("test: %.1lf%%\r",rate);// fflush(stdout);// 2. 更新进度条主体char bar[NUM]; // 这里 1% 更新一个等号memset(bar, '\0', sizeof(bar));int i = 0;//定义放到了外面,因为C99之前的for(int i; )不支持for (i = 0; i < (int)rate; i++){bar[i] = STYLE;}// 3. 更新旋转光标或者其他风格static int num = 0;num++;num %= pnum;char points[pnum + 1];memset(points, '\0', sizeof(points));//直接用上面的ifor (i = 0; i < pnum; i++){if (i < num) points[i] = POINT;else points[i] = SPACE;}// 4. test && printfprintf("[%-100s][%.1lf%%]%s\r", bar, rate, points);fflush(stdout);// sleep(1);
}
main.c
#include "process.h"
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <time.h>const int pnum = 6;typedef void(*flush_t)(double total, double current); // 刷新的函数指针类型
const int base = 100;
double total = 2048.0; // 2048MB
double once = 0.1; // 0.5MB// 进度条的调用方式
// 模拟下载行为
void download(flush_t f)
{double current = 0.0;while (current < total){int r = rand() % base + 1;double speed = r * once;current += speed;if (current >= total) current = total;usleep(10000);// 更新除了本次新的下载量// 根据真实的应用场景,来进行动态刷新//Process(total, current);f(total, current);// printf("test: %.1lf/%.1lf\r", current, total);// fflush(stdout);}printf("\n");
}int main()
{srand(time(NULL));download(FlushProcess);download(FlushProcess);download(FlushProcess);return 0;
}
进度条演示
4. Linux上git的操作
4.1 上传
(1) 首先是在自己的gitee上新建远端仓库,然后复制仓库的地址。
(2) git clone
(3)git add [file name]
注:git add . 可以新增当前目录下所有未增文件
(4)git commit -m " "
-m选项代表的是本次的提交日志
" " 里面应该表明提交日志、描述改动的详细内容,务必培养这个好习惯。
(5)git push
4.2 git操作时遇到的问题
(1)为什么会提交失败
解决:
提示:Please tell me who you are.
翻译过来就是:请告诉我你是谁。
就是说这里git无法识别你是谁,你需要告诉 git 你的身份。
其实提示已经告诉了你的问题:git config --global user.email "you@example.com" git config --global user.name "Your Name"
我们直接用上面指令输入自己gitee上对应的邮箱名和名字即可
注:
💢💢git config命令的–global参数,用了这个参数,表示你这台机器上所有的Git仓库都会使用这个配置,当然也可以对某个仓库指定不同的用户名和Email地址。
而且我们也可以通过 git config -l 来查看配置信息
(2)push时出现的警告
warning: push.default is unset; its implicit value is changing in
Git 2.0 from 'matching' to 'simple'. To squelch this message
and maintain the current behavior after the default changes, use:git config --global push.default matchingTo squelch this message and adopt the new behavior now, use:git config --global push.default simpleSee 'git help config' and search for 'push.default' for further information.
(the 'simple' mode was introduced in Git 1.7.11. Use the similar mode
'current' instead of 'simple' if you sometimes use older versions of Git)
什么意思呢?简单来说:
git push其实有多种模式,不同的模式对应着不同的操作:今天我们简单看看上面提到的matching(匹配模式)和simple(简单模式):
matching
:这是 Git 之前默认的模式simple
:这是一种适合初学者的模式,并且在 Git 2.0 之后默认就是这个模式💢💢其具体区别我并不关心,什么分支匹配、什么推送拉取,先把 git 用起来,其他问题以后再说
matching
是之前默认的,正常使用肯定是没问题的;而simple
是现在默认的,我看了一下,大概就是在推送时会进行一些检查,更适合新手。我在这里还是选用之前默认的matching
模式💢💢实际上这并不是一个报错,而是一个提示,你会发现在警告(warning)之后依然可以正常输入用户名和密码,因为他默认已经帮你选好了,就是
simple
模式,现在只是提醒你一下而已
解决方法:
- 既然我们知道了这只是一个提示信息,而并非报错,那解决起来就很简单了
- 根据 warning 的提示,选定一个默认的推送模式即可
# 执行此命令以选择旧版 git 的默认推送模式,并消除提示信息
git config --global push.default matching
# 执行此命令以选择旧版 git 的默认推送模式,并消除提示信息
git config --global push.default matching
- 任意选择一个模式后,再进行
git push
指令的操作,就不会有警告了
4.3 git的小知识
(1)git status 可以查看git仓库状态
比如当我们新建了一个 test.c文件
‘
若git add后则变成
(2)git log 查看提交日志
(3) git pull
当我们 git push 出现下面的问题时
这个可能是由于 git 远端仓库 与本地仓库不一致的原因,因此我们可以用git pull 在git push 之前
📖总结
以上就是进度条实现 && Linux下git 的远程上传的全部内容啦!!!
💞 💞 💞那么本篇到此就结束,希望我的这篇博客可以给你提供有益的参考和启示,感谢大家支持!!!祝大家天天开心
相关文章:

【Linux详解】进度条实现 Linux下git 的远程上传
📃个人主页:island1314 🔥个人专栏:Linux—登神长阶 ⛺️ 欢迎关注:👍点赞 👂🏽留言 😍收藏 💞 💞 💞 🚀前言 &#x…...

Android进阶之路 - res、raw、assets 资源解析、区别对比
那天遇到一个资源目录层级的问题,索性重新整理记录一下,希望能帮到如吾往昔之少年的你们,哈哈哈哈哈哈… 一脸茫然,越写越多,时间成本属实有点大,就当一起来基础扫盲吧 resdrawablemipmapvaluescolor asset…...

从数字化到数智化:消费零售企业如何实现门店数智化管理?
随着信息技术的飞速发展,数字化已成为企业转型的必经之路。然而,数字化本身并不是目的,而是通往数智化的桥梁。数智化,即数据智能化,是指企业通过数字化手段收集和分析数据,进而利用这些数据驱动决策和创新…...
Linux中ES的安装
文章目录 一、ES是什么1.1、ES概念介绍1.2、技术架构1.2.1、Lucene介绍 1.3、ES的工作原理1.4、ES的适用场景 二、安装前的配置2.1、创建普通用户2.2、调整文件描述符数量和虚拟内存2.3、设置shell会话的资源限制(软限制和硬限制)2.4、增加虚拟内存的设置…...

Redis远程字典服务器(5) —— hash类型详解
目录 一,hash基本情况 二,hash常用命令详解 2.1 hset,hget,hexists,hdel 2.2 hexists,hdel 2.3 hkeys,hvals 2.4 hgetall,hmget 2.5 hlen,hsetnx 2.6 hincrby&am…...

MySQL | 行锁——记录锁、间隙锁 、临键锁、插入意向锁
1、InnoDB中的行锁 行锁(Row Lock) 也称为记录锁,顾名思义,就是锁住某一行(某条记录row)。需要注意的是,MySQL服务器层并没有实现行锁机制,行级锁只在存储引擎层实现。 优点&#x…...

【网络编程】TCP通信基础模型实现
tcpSer.c #include <myhead.h> #define SER_IP "192.168.119.143" // 设置IP地址 #define SER_PORT 6666 // 设置端口号 int main(int argc, const char *argv[]) {// 1.创建socketint serfd socket(AF_INET, SOCK_STREAM, 0);// 参数1表示ipv4// 参数2表…...

css rem之2024
话题开始前 我们都知道1rem是等于html fontSize标签的字体大小的,我们主要用来做移动端网页设计稿等比例在手机上面的显示。 看到的问题 这个html fontsize的大小是通过js动态计算的,而这个js的运行时晚于html渲染的,所以会导致一个问题&am…...

python自动化笔记:pytest框架
目录 一、pytest介绍二、测试用例命名规则2.1、pytest命名规则2.2、python命名规范 三、pytest运行方式3.1、主函数方式3.2、命令行方式3.3、通过pytest.ini的配置文件运行(常用) 四、跳过测试用例4.1 无条件跳过4.2 有条件跳过 五、用例的前后置&#x…...
wpf 路径动画 举例
先,我们需要在XAML中定义一个Path,这个Path将定义动画的路线。然后,我们将使用DoubleAnimationUsingPath来沿着这个路径移动一个元素(比如一个矩形)。 <Window x:Class"WpfApp.MainWindow" xmlns"…...
【C++】classes and object 2.8 取地址及const取地址操作符重载
这两个默认成员函数一般不用重新定义 ,编译器默认会生成。 #define _CRT_SECURE_NO_WARNINGS 1 #include <iostream> using namespace std; class Date { public:Date* operator&(){return this;}const Date* operator&()const{return this;} privat…...

milvus helm k8s开启监控
https://milvus.io/docs/monitor.md 文章写的很清晰 ,我这边做一下个人补充,初版可能只是配置,具体的grafana 监控报表后期补一下。 架构如下: values.yaml 配置 enabled: true 改为true metrics:enabled: trueserviceMonitor:…...
牛奶饮用学习笔记
1. 常见牛奶类型 1.1 蒙牛-每日鲜语-0脂肪鲜牛奶 项目每100mL NRV%能量146kJ 能量计算 250 mL 146 kJ / 100 mL 365 kJ 250\text{mL}\times146\text{kJ}/100\text{mL} 365\text{kJ} 250mL146kJ/100mL365kJ 1.2 伊利-舒化-高钙型无乳糖牛奶 项目每100mL NRV%能量269kJ …...
php防止页面重复刷新或者重复提交
2.核心代码 显示的逻辑: //获取防止刷新的唯一标识符,start $intFlag substr(md5(time()),6); $strFlag BAOXIAOSS_.$my_user_id.$intFlag; $smarty->assign(check_is_agin_post, $strFlag); //获取防止刷新的唯一标识符,end注意:前端页面提交加入…...

Springboot3 配置sql打印到控制台
一、pom.xml <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-log4j2</artifactId><version>3.1.2</version></dependency> 二、application.yml com.lingyang.system # log4j2配…...
深入理解 GO 语言并发
1. 使用并发 在深入了解 Go 如何处理并发之前,先查看并发的概念。在计算机发展的早期阶段,计算机系统只有一个处理器负责执行所有指令。由于这种体系结构,计算机程序被编写成以串行的方式运行,在这种方式下,程序按照预定义的顺序逐个指令地执行。 随着计算机程序变得越来越…...

leetcode39组合总和
题目描述 给你一个 无重复元素 的整数数组 candidates 和一个目标整数 target ,找出 candidates 中可以使数字和为目标数 target 的 所有 不同组合 ,并以列表形式返回。你可以按 任意顺序 返回这些组合。 candidates 中的 同一个 数字可以 无限制重复被选…...

【JPCS独立出版,EI稳定检索】2024年工业机器人与先进制造技术国际学术会议(IRAMT 2024,9月27-29)
2024年工业机器人与先进制造技术国际学术会议(IRAMT 2024)将于2024年9月27-29日在中国成都举办。 此次会议将围绕工业机器人、机电技术、机械及制造等领域的最新研究成果展开讨论,并广泛邀请了国内外领域内的著名专家与学者。会议旨在搭建一个…...

Fal.ai Flux 1-Pro/Viva.ai/哩布哩布AI:AI绘图部分免费工具+原图提示词Prompt
目录 #1 找软件 #2 懂提示词 #3 更难的一步,会英文 我个人认为,想要玩文生图,你要会3个步骤: #1 找软件 主流文生图软件:Midjourney、Stable Diffusion、Dall-E 3 巧了,我用的都是小众、免费的画笔工…...
C++学习笔记----2、使用C++进行优雅编程(十)---- 格式化
许多人因为编程风格的问题被搞得焦头烂额,就因为对于在if中使用几个空格争论不休,导致友谊的小船说翻就翻。如果公司有相应的编程规范,只能说你比较幸运。因为有可能你不喜欢这些规范,但做为一个正常人来讲,至少有规范…...

Python:操作 Excel 折叠
💖亲爱的技术爱好者们,热烈欢迎来到 Kant2048 的博客!我是 Thomas Kant,很开心能在CSDN上与你们相遇~💖 本博客的精华专栏: 【自动化测试】 【测试经验】 【人工智能】 【Python】 Python 操作 Excel 系列 读取单元格数据按行写入设置行高和列宽自动调整行高和列宽水平…...
服务器硬防的应用场景都有哪些?
服务器硬防是指一种通过硬件设备层面的安全措施来防御服务器系统受到网络攻击的方式,避免服务器受到各种恶意攻击和网络威胁,那么,服务器硬防通常都会应用在哪些场景当中呢? 硬防服务器中一般会配备入侵检测系统和预防系统&#x…...

BCS 2025|百度副总裁陈洋:智能体在安全领域的应用实践
6月5日,2025全球数字经济大会数字安全主论坛暨北京网络安全大会在国家会议中心隆重开幕。百度副总裁陈洋受邀出席,并作《智能体在安全领域的应用实践》主题演讲,分享了在智能体在安全领域的突破性实践。他指出,百度通过将安全能力…...
蓝桥杯 冶炼金属
原题目链接 🔧 冶炼金属转换率推测题解 📜 原题描述 小蓝有一个神奇的炉子用于将普通金属 O O O 冶炼成为一种特殊金属 X X X。这个炉子有一个属性叫转换率 V V V,是一个正整数,表示每 V V V 个普通金属 O O O 可以冶炼出 …...
【生成模型】视频生成论文调研
工作清单 上游应用方向:控制、速度、时长、高动态、多主体驱动 类型工作基础模型WAN / WAN-VACE / HunyuanVideo控制条件轨迹控制ATI~镜头控制ReCamMaster~多主体驱动Phantom~音频驱动Let Them Talk: Audio-Driven Multi-Person Conversational Video Generation速…...

Linux部署私有文件管理系统MinIO
最近需要用到一个文件管理服务,但是又不想花钱,所以就想着自己搭建一个,刚好我们用的一个开源框架已经集成了MinIO,所以就选了这个 我这边对文件服务性能要求不是太高,单机版就可以 安装非常简单,几个命令就…...

C++_哈希表
本篇文章是对C学习的哈希表部分的学习分享 相信一定会对你有所帮助~ 那咱们废话不多说,直接开始吧! 一、基础概念 1. 哈希核心思想: 哈希函数的作用:通过此函数建立一个Key与存储位置之间的映射关系。理想目标:实现…...

Matlab实现任意伪彩色图像可视化显示
Matlab实现任意伪彩色图像可视化显示 1、灰度原始图像2、RGB彩色原始图像 在科研研究中,如何展示好看的实验结果图像非常重要!!! 1、灰度原始图像 灰度图像每个像素点只有一个数值,代表该点的亮度(或…...
React父子组件通信:Props怎么用?如何从父组件向子组件传递数据?
系列回顾: 在上一篇《React核心概念:State是什么?》中,我们学习了如何使用useState让一个组件拥有自己的内部数据(State),并通过一个计数器案例,实现了组件的自我更新。这很棒&#…...
【题解-洛谷】P10480 可达性统计
题目:P10480 可达性统计 题目描述 给定一张 N N N 个点 M M M 条边的有向无环图,分别统计从每个点出发能够到达的点的数量。 输入格式 第一行两个整数 N , M N,M N,M,接下来 M M M 行每行两个整数 x , y x,y x,y,表示从 …...