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系统中复杂的开发项目,都离不开这些基础工具的使用。

相关推荐
RisunJan36 分钟前
【HarmonyOS】鸿蒙开发语言的选择
开发语言·华为·harmonyos
Mai Dang36 分钟前
黑马Linux学习笔记
linux·笔记·学习·阿里云
雨落在了我的手上37 分钟前
C语言入门(二十五):自定义类型:结构体
c语言·开发语言
Yan-英杰38 分钟前
openEuler 25.09 VM虚拟机实测:性能与安全双维度测评
服务器·开发语言·科技·ai·大模型
兩尛39 分钟前
HJ52 计算字符串的编辑距离
java·开发语言·算法
en-route39 分钟前
软件生命周期全解析:从开发到运维的全流程管理
运维
武子康41 分钟前
Java-183 OSS 上传实战:Java 原生与 Spring Boot 集成
java·开发语言·spring boot·分布式·spring·阿里云·oss
beijingliushao41 分钟前
99-在Linux上安装Anaconda
linux·运维·服务器·spark
wanhengidc42 分钟前
弹性云服务器的安全保障都有哪些?
运维·服务器·科技·安全·智能手机