Linux基础开发工具(上):从包管理到“进度条”项目实战,掌握 yum/vim/gcc 核心工具


文章目录


引言

作为 Linux 开发的入门者,掌握 "软件安装→代码编辑→编译构建" 的基础流程是打通开发链路的关键。日常开发中,我们常面临 "如何快速安装工具","用什么编辑代码","怎样将代码转为可执行程序" 等问题,这些都离不开 yum/apt、vim、gcc/g++、Makefile 等核心工具的支撑。


1.软件包管理器:yum和apt

1.1.为什么需要包管理器?

在Linux中手动编译源代码安装软件不仅繁琐,还会面临依赖问题 。包管理器就像"应用商店",能自动解决依赖、下载编译好软件包。

在Linux系统下,不同发行版对应不同的工具:

  • CentOs/RHEL :使用yum(Yellow dog Updater,Modified);
  • Ubuntu/Debian :使用apt(Advanced Package Tool)。

国内镜像源能解决官方源下载慢的问题,常用镜像源如下:
阿里云镜像站
清华大学开源镜像站
中科大镜像站

1.2.从查询到卸载的完整流程

1.2.1.查看安装包

想知道系统中是否有lrzsz(串口传输工具),可以用一下命令筛选:

bash 复制代码
# CentOS(yum)
yum list | grep lrzsz
# 输出示例:lrzsz.x86_64    0.12.20-36.el7    @base

# Ubuntu(apt)
apt search lrzsz
# 输出示例:lrzsz/focal,now 0.12.21-10 amd64 [installed]

1.2.2.安装文件

安装gcc编译器,-y参数表示自动确认:

bash 复制代码
# CentOS
sudo yum install -y gcc

# Ubuntu
sudo apt install -y gcc

1.2.3.卸载软件

卸载不需要的lrzsz

bash 复制代码
# CentOS
sudo yum remove -y lrzsz

# Ubuntu
sudo apt remove -y lrzsz

1.2.4.源配置:更换国内镜像源

以 CentOS 7 更换阿里云镜像源为例:

bash 复制代码
# 1. 备份原有源
sudo mkdir /etc/yum.repos.d/backup
sudo mv /etc/yum.repos.d/*.repo /etc/yum.repos.d/backup/

# 2. 下载阿里云源配置文件
sudo curl -o /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo

# 3. 清理缓存并生成新缓存
sudo yum clean all
sudo yum makecache

2.编辑器Vim

vim是Linux默认的全功能编辑器,能够实现多模式间切换。

2.1.核心模式

  • 命令模式(Normal mode):控制光标、删除复制文本;
  • 插入模式(Insert mode):输入文字(左下角显式--INSERT--);
  • 底行模式(last line mode):执行保存、退出、列行号等操作。

2.2.常用命令

2.2.1.光标移动(命令模式)

bash 复制代码
h/j/k/l    # 左/下/上/右移动(替代方向键)
gg         # 跳至文件开头
G          # 跳至文件结尾
$          # 跳至当前行末尾
^          # 跳至当前行开头
w          # 跳至下一个单词开头
e          # 跳至下一个单词结尾
5l         # 向右移动5个字符(数字+操作)

2.2.2.编辑操作(命令模式)

bash 复制代码
# 删除
x          # 删除光标所在字符
dd         # 删除当前行
3dd        # 删除从当前行开始的3行
X          # 删除光标前一个字符

# 复制粘贴
yy         # 复制当前行
2yy        # 复制从当前行开始的2行
p          # 粘贴到光标后
P          # 粘贴到光标前

# 替换与撤销
r          # 替换光标所在字符(只换一个)
R          # 连续替换(直到按ESC)
u          # 撤销上一步操作
Ctrl+r     # 恢复撤销(反撤销)

2.2.3.底行模式常用命令

bash 复制代码
:set nu    # 显示行号(nu=number)
:set nonu  # 隐藏行号
:/keyword  # 向下查找关键字(按n下一个,N上一个)
:?keyword  # 向上查找关键字
:w         # 保存文件(write)
:wq        # 保存并退出(write+quit)
:q!        # 强制退出(不保存,!表示强制)
:15        # 跳至第15行

2.3.简单vim配置

  • 如果想个性化配置vim,可以在当前要配置的用户主目录下创建.vimrc文件,添加以下配置:
bash 复制代码
# ~/.vimrc 配置示例
syntax on          " 开启语法高亮(代码颜色区分)
set nu             " 默认显示行号
set shiftwidth=4   " 缩进时的空格数(默认4个)
set tabstop=4      " Tab键对应4个空格
set autoindent     " 自动缩进(新行继承上一行缩进)
set cursorline     " 高亮当前行(方便定位)
  • 想要一键化配置更好看的vim,可以访问以下链接:VimForCpp

2.4.vim高频指令速查表

功能分类 命令 说明
模式切换 i 命令模式 -> 插入模式(光标前)
a 命令模式 -> 插入模式(光标后)
Shift + ; 命令模式 -> 底行模式
保存退出 :wq 退出并保存
q! 强制退出
查找替换 :%s/old/new/g 全文替换oldnew%=全文,g=全局)
行操作 dd + p 剪切并粘贴
yy + np 复制当前行并粘贴n(数字)次

3.编译器:gcc/g++

3.1.编译流程

  • 预处理:主要包括展开头文件、宏替换、去注释等;
  • 编译:检查代码的规范性、是否有语法错误等,并将代码转成汇编语言;
  • 汇编:将汇编代码翻译成二进制可重定向目标文件(机器码);
  • 链接:将目标文件与系统库结合,生成可执行文件。

3.2.编译完整流程演示

hello.c(打印Hello Linux)程序为例:

  • 预处理阶段(生成.i文件)
bash 复制代码
gcc -E hello.c -o hello.i
# -E:只执行预处理,不进行后续步骤
# -o:指定输出文件(hello.i)
  • 编译阶段(生成.s文件)
bash 复制代码
gcc -S hello.i -o hello.s
# -S:只执行预处理和编译,生成汇编代码

此时,hello.s文件中是汇编指令,如:

bash 复制代码
main:
    pushq   %rbp
    movq    %rsp, %rbp
    movl    $.LC0, %edi
    call    puts
    movl    $0, %eax
    popq    %rbp
    ret
.LC0:
    .string "Hello Linux"
  • 汇编阶段(生成.o文件)
bash 复制代码
gcc -c hello.s -o hello.o
# -c:只执行预处理、编译、汇编,生成目标文件

.o是二进制文件,无法直接查看,需用objdump工具分析:

bash 复制代码
objdump -d hello.o  # 查看目标文件的汇编指令
  • 链接阶段
bash 复制代码
gcc hello.o -o hello
# 无特殊参数,默认链接动态库

运行可执行文件:

bash 复制代码
./hello  # 输出:Hello Linux
  • 一键编译(跳过中间文件)
bash 复制代码
gcc hello.c -o hello  # C语言
g++ hello.cpp -o hello  # C++语言

3.3.静态链接 vs 动态链接

特性 静态链接(.a库) 动态链接(.so库)
编译参数 gcc -static hello.c -o hello gcc hello.c -o hello(默认)
文件大小 较大(包含库代码) 较小(运行时加载库)
运行依赖 不依赖系统库(可移植性强) 依赖系统库安装对应动态库
更新维护 库更新需重新编译程序 库更新无需重新编译程序
适用场景 需移植到无对应库的环境 日常开发(节省内存和磁盘)

查看可执行文件的依赖库:

bash 复制代码
ldd hello  # 查看动态链接的库
# 输出示例:libc.so.6 => /lib64/libc.so.6(依赖C标准库)

4.自动化构建:-make/Makefile

当工程中有多个源文件(如:main.cfunc1.cfunc2.c)时,手动输入gcc命令编译会非常繁琐。Makefile能定义"依赖关系"和"编译命令",只需执行make就能自动完成所有源文件的编译,还能清理中间文件。

4.1.核心概念

  • 目标(Target):要生成的目标文件(如可执行文件、目标文件等);
  • 依赖(Prerequisites):生成目标需要的文件(如.c文件、.0文件);
  • 依赖方法(Recipe):生成目标的命令(如gcc -c main.c -o main.o)。

格式如下:

bash 复制代码
Target: Prerequisite1, Prerequisite2 ...
	Recipe(命令前必须是Tab,不能是空格)

4.2.简单Makefile(单文件)

myproc.c(计算1-100的和)为例,编写Makefile文件:

bash 复制代码
# Makefile示例(单文件)
myproc: myproc.c  # 目标:myproc;依赖:myproc.c
    gcc -o myproc myproc.c  # 编译命令(Tab开头)

.PHONY: clean  # 声明clean为伪目标(避免与同名文件冲突)
clean:  # 清理目标(无依赖,执行make clean时触发)
    rm -f myproc  # 删除可执行文件

使用方法:

bash 复制代码
make          # 编译生成myproc
make clean    # 清理myproc(删除可执行文件)

4.3.进阶Makefile(多文件)

假设有三个文件:main.c(主函数)、add.c(加法函数)、add.h(头文件),工程结构如下:

bash 复制代码
project/
├── main.c
├── add.c
├── add.h
└── Makefile

编写支持多文件的Makefile,使用变量简化维护:

bash 复制代码
# 定义变量(方便修改,类似代码中的宏)
BIN = calc          # 可执行文件名
SRC = $(wildcard *.c)  # 所有.c文件(main.c、add.c)
OBJ = $(SRC:.c=.o)  # 将.c替换为.o(main.o、add.o)
CC = gcc            # 编译器
CFLAGS = -Wall -g   # 编译选项(显示警告+生成调试信息)

# 目标:可执行文件calc,依赖所有.o文件
$(BIN): $(OBJ)
    $(CC) $(CFLAGS) -o $@ $^  # $@=目标名,$^=所有依赖
    @echo "编译完成!可执行文件:$(BIN)"  # @:不显示命令本身

# 目标:.o文件,依赖对应的.c和.h文件(自动推导)
%.o: %.c
    $(CC) $(CFLAGS) -c $< -o $@  # $<=第一个依赖(.c文件)

# 伪目标:清理中间文件和可执行文件
.PHONY: clean
clean:
    rm -f $(OBJ) $(BIN)
    @echo "清理完成!"

使用方法:

bash 复制代码
make          # 编译生成calc(自动生成main.o、add.o)
./calc        # 运行程序
make clean    # 清理main.o、add.o、calc

4.4.伪目标.PHONY

  • 我们一般把clean设置成伪目标,伪目标的特性是,总是被执行的

  • .PHONY让make忽略源文件和可执行文件的M时间(文件内容修改时间)对比

如果工程中恰好有一个名为clean的文件,执行make clean时,make 会认为 "目标文件已存在且无依赖更新",不会执行清理命令。声明为伪目标后,make 会忽略同名文件,强制执行clean对应的命令。


5.编写第一个Linux程序:进度条

5.1.核心知识点

  • 回车(\r):光标回到当前行开头;
  • 换行:光标跳到下一行,现代计算机语言中的\n实际上包含了回车和换行两部分;
  • 行缓冲区:printf默认会输出到缓冲区,遇到\n或手动刷新(fflush(stdout))才会显示。

5.2.完整代码实现

5.2.1.头文件:process.h

c 复制代码
// process.h
#pragma once
#include <stdio.h>

// 版本1:固定进度(0-100%)
void process_v1();

// 版本2:动态进度(根据当前进度更新)
// total:总任务量,current:当前完成量
void FlushProcess(double total, double current);

5.2.2.源文件:process.c(实现进度条逻辑)

c 复制代码
// process.c
#include "process.h"
#include <string.h>
#include <unistd.h>  // 包含usleep函数(微秒级休眠)

#define NUM 101      // 进度条缓冲区大小(100个字符+1个结束符)
#define STYLE '='    // 进度条填充字符

// 版本1:固定进度
void process_v1() {
    char buffer[NUM] = {0};  // 初始化缓冲区(全0)
    // 旋转光标(|/-\),实现动态效果
    const char *lable = "|/-\\";
    int len = strlen(lable);  // 长度4

    for (int cnt = 0; cnt <= 100; cnt++) {
        // 格式化输出:进度条(左对齐100字符)、百分比、旋转光标
        printf("[%-100s][%d%%][%c]\r", buffer, cnt, lable[cnt % len]);
        fflush(stdout);  // 手动刷新缓冲区(否则不显示)
        
        buffer[cnt] = STYLE;  // 填充进度条
        usleep(50000);  // 休眠50ms(控制进度条速度)
    }
    printf("\n");  // 进度条结束后换行
}

// 版本2:动态进度
void FlushProcess(double total, double current) {
    char buffer[NUM] = {0};
    const char *lable = "|/-\\";
    int len = strlen(lable);
    static int cnt = 0;  // 静态变量(记录旋转光标位置,不重置)

    // 计算当前进度百分比(转为整数)
    int progress = (int)(current * 100 / total);
    // 填充进度条缓冲区
    for (int i = 0; i < progress; i++) {
        buffer[i] = STYLE;
    }

    // 计算进度率(保留1位小数)
    double rate = current / total;
    cnt %= len;  // 循环使用旋转光标
    printf("[%-100s][%.1f%%][%c]\r", buffer, rate * 100, lable[cnt]);
    fflush(stdout);
    cnt++;
}

5.2.3.主函数:main.c(模拟下载场景)

c 复制代码
// main.c
#include "process.h"
#include <unistd.h>

#define TOTAL_SIZE 1024.0  // 模拟总文件大小(1024MB)
#define SPEED 10.0         // 模拟下载速度(10MB/次)

// 模拟下载过程
void DownLoad() {
    double current = 0.0;  // 当前已下载大小
    while (current <= TOTAL_SIZE) {
        FlushProcess(TOTAL_SIZE, current);  // 更新进度条
        usleep(100000);  // 休眠100ms(模拟下载耗时)
        current += SPEED;  // 累加已下载大小
    }
    printf("\n下载完成!总大小:%.2lfMB\n", current);
}

int main() {
    printf("开始模拟下载...\n");
    DownLoad();  // 执行下载(显示进度条)
    return 0;
}

5.2.4.Makefile:自动化编译

bash 复制代码
# Makefile
SRC = $(wildcard *.c)  # main.c、process.c
OBJ = $(SRC:.c=.o)    # main.o、process.o
BIN = processbar       # 可执行文件名
CC = gcc
CFLAGS = -Wall -g      # 显示警告+调试信息

$(BIN): $(OBJ)
    $(CC) -o $@ $^

%.o: %.c
    $(CC) $(CFLAGS) -c $< -o $@

.PHONY: clean
clean:
    rm -f $(OBJ) $(BIN)

5.3.运行效果:

生成可执行文件,并运行:

bash 复制代码
make          # 编译生成processbar
./processbar  # 运行程序

输出如下:

bash 复制代码
开始模拟下载...
[==================================================        ][50.0%][/]

最终显示:

bash 复制代码
开始模拟下载...
[====================================================================================================][100.0%][|]
下载完成!总大小:1030.00MB

结语

本文从软件包管理器的 "依赖解决",到 vim 的 "多模式编辑",再到 gcc 的 "四阶段编译" 与 Makefile 的 "自动化构建",最后通过"进度条"项目完成了以上工具的实战使用,今后LInux系统中复杂的开发项目,都离不开这些基础工具的使用。

相关推荐
蚰蜒螟4 分钟前
从mkdir命令到磁盘:Linux内核目录创建过程深度解析
linux·运维·数据库
念何架构之路5 分钟前
接入层Nginx
运维·nginx
wanhengidc8 分钟前
云手机 跨设备无缝衔接
运维·服务器·人工智能·智能手机·云计算
sxlishaobin9 分钟前
SSH远程免密登录的两种方式
运维·ssh
摇滚侠11 分钟前
01 基础语法 JavaScript 入门到精通全套教程
开发语言·javascript·ecmascript
sleven fung11 分钟前
Milvus 向量数据库
开发语言·数据库·python·langchain·milvus
大大杰哥35 分钟前
Java 日志框架详解:SLF4J + Logback 从入门到实战
java·开发语言·logback
coward9141 分钟前
Linux内核驱动初始化流程认识(关于late_initcall和modul_init驱动初始化宏差异)
linux·嵌入式硬件
ylscode43 分钟前
黑客利用 GHOSTYNETWORKS 和 OMEGATECH 托管 JS 恶意软件基础设施
开发语言·安全·php·安全威胁分析
modelmd43 分钟前
Linux man 命令详解:从入门到精通
linux