您的位置:首页 > 运维架构 > Shell

在Linux下编写一个进度条的小程序:C和shell

2017-02-17 13:35 435 查看
写一个简单的进度条了解三个方面的知识:进度条的实现原理,Linux下的回车,以及缓冲区

(1)进度条的实现原理:定义一个102的字符数组bar[102],首先第一个位置bar[0] ='\0',在while循环中:每次更新从0的位置开始写入n 个‘*’(每次从开始位置写入 涉及到回车问题),更新到100结束,n来控制进度条的进度或者写入多少个*。

(2)Linux下的回车问题:

Unix 系统里,每行结尾只有“<换行>”,即“\n”;Windows系统里面,每行结尾是“<回车><换行>”,即“ \r\n”;Mac

系统里,每行结尾是“<回车>”。一个直接后果是,Unix/Mac系统下的文件在Windows里打开的话,所有文字会变成

一行;而Windows里的文件在Unix/Mac下打开的话,在每行的结尾可能会多出一个^M符号。

    在windows系统中,当你输入回车时会自动变成\r\n;在linux下的回车键只代表\n。

 

(3)缓冲区:

全缓冲:linux下默认为8192字节,在缓冲区满或者显示调用刷新函数后进行IO系统调用操作,
普通磁盘文件通常使用全缓冲区访问。
行缓冲区:默认大小为128字节,当在遇到换行符或者缓冲区满时,标准IO库执行IO系统调用操作,终端即行缓冲区。
非缓冲区:标准IO库不对字符进行缓存,标准出错流stderr通常是不带缓冲区的。

用printf()输出时是先输出到缓冲区,然后再从缓冲区送到屏幕上。Linux下缓冲区刷新到屏幕的方式:
1使用fflush(stdout)强制刷新标准输出缓冲区。
2.缓冲区已满。
3.scanf()要在缓冲区里取数据时会先将缓冲区刷新。
4.\n进入缓冲区时。
5. 程序结束时。

 下面实现进度条:

  

#include<stdio.h>
#include<unistd.h>
int main()
{
int i=0;
char bar[102];
const char *label ="-\\|/";
bar[0] = '\0';
while(i<=100)
{
printf("[%-101s][%d%%][%c]\r",bar,i,label[i%4]);
fflush(stdout);
bar[i++] = '#';
bar[i] = '\0';
sleep(1);
}
printf("\n");
return 0;
}


makefile:

bar:bar.c
gcc -o bar bar.c
.PHONY:clean
clean:
rm -f bar


shell脚本实现一个进度条

最近学习了shell脚本语言,现在用shell脚本语言实现同一样的进度条。

首先介绍一个下在脚本语言和C语言在编写进度条的一个区别

shell脚本语言中:

printf 是一个命令语句,在bash中执行时,是fork一个子进程,运行这个命令,命令结束后,子进程退出,然后缓存区直接刷新。

而在C语言中始终在一个进程中运行,所以得用fflush刷新缓存区

直接贴代码吧,有上面的基础+shell脚本基本的语法,很容易理解

#!/bin/bash

color=(31 33 35 32 34 36)

col_idx=0
i=0
str=""
laber=('|' '/' '-' '\\')
idx=0
while [ $i -le 100 ]
do
str+='#'
#printf "[%-100s] [%d%%] [%c]\r" "$str" "$i" ${laber[$dix]}
printf "[\e[1;%dm%-100s]\e[0m [%d%%] [\e[1;31m%c\e[0m]\r" "${color[$col_idx]}" "$str" "$i" "${laber[$idx]}"
let i++
let idx++
let col_idx++
let idx%=4
let col_idx%=6
usleep 100000
done
printf "\n"


脚本中第二个printf是加了颜色的,

printf可以对输出的内容进行修改颜色,

printf"\e[字背景颜色;字体颜色m
字符串 \e[0m"

\e[0m 是恢复颜色的标志
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: