学 Linux_day7 编写第一个Bash脚本,实现一键编译运行第一个C程序

学 Linux_day7 编写第一个Bash脚本,实现一键编译运行第一个C程序 第一个 Bash 脚本一键编译运行 Hello World一、我们之前怎么做之前写好了hello.c后操作过程是gcc hello.c-ohello ./hello每次修改代码后都要重复敲这两条命令。现在我们把它写进一个脚本以后只要一条命令就能自动完成编译 运行。二、什么是 Bash 脚本Bash 脚本就是一个纯文本文件里面按顺序写着终端命令。运行这个脚本就相当于把你手动敲的命令自动执行一遍。类比你手动编译运行自己一步步操作Bash 脚本把步骤写成“剧本”由计算机自动表演优点避免重复输入提高效率可以加入判断、循环让操作更智能方便分享给他人保证操作一致性三、准备工作确认你的第一个 C 程序我们在家目录下新建一个工作目录并把之前的hello.c放进去如果还没有现在就创建一个mkdir-p~/my_first_scriptcd~/my_first_scriptnanohello.chello.c内容最简单的 Hello World#includestdio.hintmain(){printf(Hello, Linux!\n);return0;}保存退出。我们先手动编译运行一次确保一切正常gcc hello.c-ohello ./hello看到Hello, Linux!输出说明程序没问题。四、编写第一个脚本build_run.sh用编辑器创建脚本文件nanobuild_run.sh输入以下内容#!/bin/bash# # 脚本: build_run.sh# 功能: 一键编译 hello.c 并运行生成的可执行文件# SOURCEhello.c# 源文件TARGEThello# 可执行文件名echo正在编译$SOURCE...gcc-g-O0-o$TARGET$SOURCE# 检查编译是否成功$? 是上一条命令的退出码0 表示成功if[$?-eq0];thenecho编译成功正在运行$TARGET...echo./$TARGETelseecho编译失败请检查代码。exit1fi保存并退出CtrlO回车CtrlX。五、逐行讲解脚本的每一部分行解释#!/bin/bashShebang告诉系统用/bin/bash解释器执行本脚本。必须是第一行。# ...以#开头是注释给人看的不执行。SOURCEhello.c定义变量SOURCE值为hello.c。等号两边不能有空格。TARGEThello定义变量TARGET值为可执行文件名。echo 正在编译 $SOURCE ...echo打印信息。$SOURCE会被替换成hello.c。gcc -g -O0 -o $TARGET $SOURCE编译命令-g包含调试信息-O0不优化。变量用双引号括起来防止意外。if [ $? -eq 0 ]; then$?是上一条命令的退出码。-eq 0判断是否等于 0。整句意思是“如果编译成功那么…”echo 编译成功...提示编译成功。echo 装饰性分隔线。./$TARGET运行可执行文件。else否则编译失败执行下面部分。echo 编译失败...提示失败。exit 1脚本以非 0 状态退出表示异常终止。六、赋予脚本执行权限Linux 下新建文件默认没有执行权限需要手动添加chmodx build_run.shx表示添加执行权限。可以用ls -l检查应该看到类似-rwxr-xr-x的权限。七、运行脚本直接在当前目录执行./build_run.sh你会看到正在编译 hello.c ... 编译成功正在运行 hello ... Hello, Linux!完美以后修改hello.c后只需再运行一次./build_run.sh即可无需手动敲两条命令。八、让脚本更通用支持任意.c文件目前的脚本写死了文件名。我们可以改进一下让它能从命令行接收源文件名。创建build.sh通用版#!/bin/bash# 通用编译运行脚本# 用法: ./build.sh 源文件.cif[$#-eq0];thenecho用法:$0源文件.cexit1fiSRC$1OUT${SRC%.c}# 去掉 .c 后缀作为可执行文件名echo编译$SRC-$OUT...gcc-g-O0-o$OUT$SRCif[$?-eq0];thenecho编译成功运行 ./$OUT..../$OUTelseecho编译失败exit1fi关键点解释$#传递给脚本的参数个数。$0脚本自己的名字。$1第一个参数例如hello.c。${SRC%.c}字符串处理去掉末尾的.c。若SRChello.c则OUThello。使用示例chmodx build.sh ./build.sh hello.c这就可以编译任何单个 C 文件只要它不依赖其他库。九、更完善的脚本加入自动化测试我们还可以把之前学过的diff结合进来让脚本自动检查输出是否正确。思路编译程序。用事先准备好的输入如果程序需要输入和预期输出文件。运行程序并将输出保存到临时文件。用diff比较实际输出和预期输出。显示测试结果。示例脚本test.sh假设程序不需要输入直接比输出#!/bin/bashgcc hello.c-ohello ./hellooutput.txtifdiff-qexpected.txt output.txt/dev/null;thenecho测试通过elseecho测试失败diff-uexpected.txt output.txtfi为后续学习自动化测试打下基础。十、练习题由浅入深基础篇在当前目录创建greet.c输出 “Hello, Script!”。然后编写脚本run_greet.sh一键编译并运行它。解释脚本中$?的含义并修改脚本使之在编译失败时用红色可选打印错误信息提示echo -e \033[31m编译失败\033[0m。不使用chmod x能否用其他方式运行脚本提示bash 脚本名进阶篇编写通用编译运行脚本build.sh如第八节然后分别用它编译运行hello.c和greet.c。在脚本中加入版本控制如果可执行文件已经存在且比源文件新则跳过编译直接运行提示用test命令比较文件时间-nt。尝试在脚本中处理gcc的警告信息如果编译有警告但成功打印 “编译成功但有警告”。提高篇写一个脚本batch_build.sh它接收多个.c文件作为参数依次编译运行每一个遇到编译失败的跳过并报告。结合diff给hello.c写一个自动化测试脚本程序输出与预期输出比较通过即打印 PASS失败打印 FAIL 并显示差异。十一、答案与解析基础篇创建greet.c内容类似。脚本只需把SOURCE改为greet.cTARGET改为greet即可。$?是上一条命令的退出码0 表示成功非 0 表示失败。添加颜色可写成echo -e \033[31m编译失败\033[0m。可以用bash build_run.sh直接运行此时不需要执行权限因为 bash 读取文件内容执行。进阶篇通用脚本使用参数./build.sh greet.c即可。判断if [ -f $OUT ] [ $OUT -nt $SRC ]; then可跳过编译-nt表示 “newer than”。可以用gcc ... 2 warnings.txt将标准错误重定向然后检查文件是否为空。提高篇batch_build.sh示例#!/bin/bashforfilein$;doif[-f$file];thenout${file%.c}gcc$file-o$outif[$?-eq0];thenecho运行$out..../$outelseecho编译$file失败fielseecho$file不存在fidone参考第九节test.sh。十二、学习检查清单Shebang 的作用是什么它必须放在第几行如何定义变量引用变量时前面要加什么符号$?、$#、$1、$0分别代表什么怎样给脚本添加执行权限脚本里如何用if判断命令是否成功${变量%.c}的含义是什么