【Linux】C语言模拟实现shell命令行(程序替换原理)
目录
一、自动化构建工具(makefile)
二、输出提示符
三、获取用户输入的数据
四、将用户输入的指令字符串进行分割:
五、执行用户输入的命令
六、发现cd命令用不了(内建命令)
原因在于:
七、处理内建命令cd:
八、存在一个小问题:
八、处理内建命令export
九、获取最近一次进程的退出码
十、处理内建命令echo
十一、让ls指令输出的内容带上颜色
十二、完整代码
上一章节我们学习了程序替换,现在我们就可以通过程序替换来模拟实现shell命令行;
前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家
点击跳转到网站
一、自动化构建工具(makefile)
myprocess:myshell.cgcc -o $@ $^ -g -std=c99 .PHONY:clean clean:rm -f myprocess
二、输出提示符
我们在命令行终端处时,一般会有这个输出提示符:
#include<stdio.h> #include<stdlib.h>//获取主机名 const char* HostName() {char* hostname = getenv("HOSTNAME");if(hostname)return hostname;else return "None"; }//获取当前登录的用户名 const char* UserName() {char* username = getenv("USER");if(username)return username;else return "None"; }//获取当前工作目录 const char* CurrentWorkDir() { char* currentworkdir = getenv("PWD");if(currentworkdir)return currentworkdir;else return "None"; }int main() {//输出提示符printf("[%s@%s %s]$ ",UserName(),HostName(),CurrentWorkDir());return 0; }
三、获取用户输入的数据
void Interactive(char out[],int size) {fgets(out,SIZE,stdin);//stdin是标准输入流,意思就是从键盘获取数据保存到commandline中out[strlen(out)-1] = '\0';//因为fgets会读取换行符,所以这步我们去掉换行。 }int main() {//输出提示符printf("[%s@%s %s]$ ",UserName(),HostName(),CurrentWorkDir());//获取用户输入的命令char commandline[SIZE];Interactive(commandline,SIZE);printf("test:%s\n",commandline);return 0; }
四、将用户输入的指令字符串进行分割:
//对字符串进行分割 void Split(char in[]) {int i = 0;argv[i++] = strtok(in,SEP);//对字符串commandline以空格作为分隔符进行切割,"ls -a -l"while(argv[i++] = strtok(NULL,SEP));//进行第二次切割时,strtok第一个参数需要传入NULL。 }int main() {//1、输出提示符printf("[%s@%s %s]$ ",UserName(),HostName(),CurrentWorkDir());//2、获取用户输入的命令char commandline[SIZE];Interactive(commandline,SIZE);printf("test:%s\n",commandline);//3、对命令行字符串进行切割Split(commandline);return 0; }
五、执行用户输入的命令
执行命令我们是用程序替换的原理,去执行对应的命令,而程序替换过后,就不会再执行之后的代码,为了避免这一点,所以我们创建子进程取进行程序替换。
void Execute() {//因为程序替换后,不会在执行之后的代码,所以这里创建子进程去执行最合适pid_t id = fork();if(id == 0){//子进程通过程序替换执行命令execvp(argv[0],argv);exit(1);}//父进程进行等待pid_t rid = waitpid(id,NULL,0);printf("run done,rid: %d\n",rid); }int main() {//1、输出提示符printf("[%s@%s %s]$ ",UserName(),HostName(),CurrentWorkDir());//2、获取用户输入的命令char commandline[SIZE];Interactive(commandline,SIZE);printf("test:%s\n",commandline);//3、对命令行字符串进行切割Split(commandline);//4、执行分割好的命令Execute();return 0; }
这样我们就能运行起来单次命令了,所以我们套个while循环,就能循环输入了:
int main() {while (1){// 1、输出提示符printf("[%s@%s %s]$ ", UserName(), HostName(), CurrentWorkDir());// 2、获取用户输入的命令char commandline[SIZE];Interactive(commandline, SIZE);printf("test:%s\n", commandline);// 3、对命令行字符串进行切割Split(commandline);// 4、执行分割好的命令Execute();}return 0; }
六、发现cd命令用不了(内建命令)
当我们使用cd命令时,发现没有起作用,比如cd -,没有返回上一次的工作目录:
原因在于:
有些命令不应该让子进程去执行的,而是应该由shell自己去执行,就不如上述的cd命令,这种命令叫内建命令。
所以我们在执行命令之前应该要先处理内建命令
七、处理内建命令cd:
char* Home() {return getenv("HOME"); }int BuildinCmd() {int ret = 0;//检查是否为内建命令,是 1,否 0if(strcmp("cd",argv[0]) == 0){//执行ret = 1;char* target = argv[1];if(!target) target = Home();//如果只输入cd,则argv[1]的值为0,则会进入if语句,默认跳转到Home()工作目录//通过系统调用chdir,改变当前工作目录chdir(target);//虽然具体的工作目录变了,但是命令行提示符中工作目录我们没有实时更新,所以还没有变//此时需要处理一下,修改PWD环境变量,这样下次循环时,命令行提示符获取的就是当前路径。snprintf(pwd,SIZE,"PWD=%s",target);putenv(pwd);}return ret; }int main() {while (1){// 1、输出提示符printf("[%s@%s %s]$ ", UserName(), HostName(), CurrentWorkDir());// 2、获取用户输入的命令char commandline[SIZE];Interactive(commandline, SIZE);// 3、对命令行字符串进行切割Split(commandline);// 4、处理内建命令int n = BuildinCmd();if(n)continue;// 5、执行分割好的命令Execute();}return 0; }
八、存在一个小问题:
问题如下图:
该现象的原因在于,用户输入指令cd ..后target字符串的内容就变成了"..",后续调用chdir,因为chdir是系统调用,内部是处理了"."和".."的,所以这里会正常执行,但后面调用snprintf函数时,pwd的值就变成了"..",这样putenv改变的环境变量的内容就变成了"..",下次循环命令行提示的地方读取到的环境变量值就为".."。
因为在这之前,我们已经用chdir函数改变了当前工作目录了,所以我们后面使用一个接口叫:getcwd(),该接口返回的就是当前工作目录,用该接口的返回传给getenv,这样环境变量就能正常修改了
int BuildinCmd() {int ret = 0;//检查是否为内建命令,是 1,否 0if(strcmp("cd",argv[0]) == 0){//执行ret = 1;char* target = argv[1];if(!target) target = Home();//如果只输入cd,则argv[1]的值为0,则会进入if语句,默认跳转到Home()工作目录//通过系统调用chdir,改变当前工作目录chdir(target);char temp[1024];getcwd(temp,1024);//虽然具体的工作目录变了,但是命令行提示符中工作目录我们没有实时更新,所以还没有变//此时需要处理一下,修改PWD环境变量,这样下次循环时,命令行提示符获取的就是当前路径。snprintf(pwd,SIZE,"PWD=%s",temp);putenv(pwd);}return ret; }
八、处理内建命令export
export是用来导入新的环境变量的,也是一个内建命令,因为只有将新环境变量导入给自己,这样才能被子进程继承下去。
直接else if 接着判断即可:
九、获取最近一次进程的退出码
十、处理内建命令echo
else if(strcmp("echo",argv[0]) == 0){ret = 1;if(argv[1] == NULL){printf("\n");}else{if(argv[1][0] == '$')//$用于查看环境变量的值{if(argv[1][1] == '?')//$?:查看进程退出码{printf("%d\n",lastcode);lastcode = 0;}else{char* e = getenv(argv[1]+1);//echo $PWDif(e) printf("%s\n",e);}}else{//如果不是以$开头,则正常打印内容printf("%s\n",argv[1]);}}}
十一、让ls指令输出的内容带上颜色
十二、完整代码
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <sys/types.h> #include <sys/wait.h>#define SIZE 1024 #define MAX_ARGC 64 #define SEP " "// 全局进程 char *argv[MAX_ARGC]; //工作目录 char pwd[SIZE]; //环境变量 char env[SIZE]; //进程退出信息 int lastcode = 0;// 获取主机名 const char *HostName() {char *hostname = getenv("HOSTNAME");if (hostname)return hostname;elsereturn "None"; }// 获取当前登录的用户名 const char *UserName() {char *username = getenv("USER");if (username)return username;elsereturn "None"; }// 获取当前工作目录 const char *CurrentWorkDir() {char *currentworkdir = getenv("PWD");if (currentworkdir)return currentworkdir;elsereturn "None"; }// 获取用户输入的命令 void Interactive(char out[], int size) {fgets(out, SIZE, stdin); // stdin是标准输入流,意思就是从键盘获取数据保存到commandline中out[strlen(out) - 1] = '\0'; // 因为fgets会读取换行符,所以这步我们去掉换行。 }// 对字符串进行分割 void Split(char in[]) {int i = 0;argv[i++] = strtok(in, SEP); // 对字符串commandline以空格作为分隔符进行切割,"ls -a -l"while (argv[i++] = strtok(NULL, SEP)); // 进行第二次切割时,strtok第一个参数需要传入NULL。并且最后会填入NULLif(strcmp(argv[0], "ls") == 0){argv[i - 1] = "--color";//即在字符串末尾加上--color选项argv[i] = NULL;} }void Execute() {// 因为程序替换后,不会在执行之后的代码,所以这里创建子进程去执行最合适pid_t id = fork();if (id == 0){// 子进程通过程序替换执行命令execvp(argv[0], argv);exit(1);}// 父进程进行等待,并查看退出信息int status = 0;pid_t rid = waitpid(id, &status, 0);if(rid == id){//使用宏解析出退出码lastcode = WEXITSTATUS(status);}// printf("run done,rid: %d\n", rid); }char* Home() {return getenv("HOME"); }int BuildinCmd() {int ret = 0;//检查是否为内建命令,是 1,否 0if(strcmp("cd",argv[0]) == 0){//执行ret = 1;char* target = argv[1];if(!target) target = Home();//如果只输入cd,则argv[1]的值为0,则会进入if语句,默认跳转到Home()工作目录//通过系统调用chdir,改变当前工作目录chdir(target);char temp[1024];getcwd(temp,1024);//虽然具体的工作目录变了,但是命令行提示符中工作目录我们没有实时更新,所以还没有变//此时需要处理一下,修改PWD环境变量,这样下次循环时,命令行提示符获取的就是当前路径。snprintf(pwd,SIZE,"PWD=%s",temp);putenv(pwd);}else if(strcmp("export",argv[0]) == 0){ret = 1;if(argv[1]){strcpy(env,argv[1]);putenv(env);}}else if(strcmp("echo",argv[0]) == 0){ret = 1;if(argv[1] == NULL){printf("\n");}else{if(argv[1][0] == '$')//$用于查看环境变量的值{if(argv[1][1] == '?')//$?:查看进程退出码{printf("%d\n",lastcode);lastcode = 0;}else{char* e = getenv(argv[1]+1);//echo $PWDif(e) printf("%s\n",e);}}else{//如果不是以$开头,则正常打印内容printf("%s\n",argv[1]);}}}return ret; }int main() {while (1){// 1、输出提示符printf("[%s@%s %s]$ ", UserName(), HostName(), CurrentWorkDir());// 2、获取用户输入的命令char commandline[SIZE];Interactive(commandline, SIZE);// 3、对命令行字符串进行切割Split(commandline);// 4、处理内建命令int n = BuildinCmd();if(n)continue;// 5、执行分割好的命令Execute();}return 0; }
相关文章:
【Linux】C语言模拟实现shell命令行(程序替换原理)
目录 一、自动化构建工具(makefile) 二、输出提示符 三、获取用户输入的数据 四、将用户输入的指令字符串进行分割: 五、执行用户输入的命令 六、发现cd命令用不了(内建命令) 原因在于: 七、处理内…...
WordPress Madara插件存在文件包含漏洞(CVE-2025-4524)
免责声明 本文档所述漏洞详情及复现方法仅限用于合法授权的安全研究和学术教育用途。任何个人或组织不得利用本文内容从事未经许可的渗透测试、网络攻击或其他违法行为。使用者应确保其行为符合相关法律法规,并取得目标系统的明确授权。 对于因不当使用本文信息而造成的任何直…...
【Java】泛型在 Java 中是怎样实现的?
先说结论 , Java 的泛型是伪泛型 , 在运行期间不存在泛型的概念 , 泛型在 Java 中是 编译检查 运行强转 实现的 泛型是指 允许在定义类 , 接口和方法时使用的类型参数 , 使得代码可以在不指定具体类型的情况下操作不同的数据类型 , 从而实现类型安全的代码复用 的语言机制 . …...
Lambda表达式的高级用法
今天来分享下Java的Lambda表达式,以及它的高级用法。 使用它可以提高代码的简洁度,使代码更优雅。 一、什么是lambda表达式 Lambda 表达式是 Java 8 引入的特性,用于简化匿名内部类的语法,使代码更简洁,尤其在处理函…...
ctfhub技能书http协议
http://challenge-ffe8afcf1a75b867.sandbox.ctfhub.com:10800/index.php curl -v -X CTFHUB http://challenge-ffe8afcf1a75b867.sandbox.ctfhub.com:10800/index.php curl:用于发送 HTTP 请求的命令行工具。 -v(--verbose):开启…...
面试题 - 微服务相关的经典问题(33道)
1.什么是微服务? 微服务(Microservices)是一种软件架构风格,将一个大型应用程序划分为一组小型、自治且松耦合的服务。每个微服务负责执行特定的业务功能,并通过轻量级通信机制(如HTTP)相互协作…...
在C#中对List<T>实现多属性排序
本文介绍了四种实现多级排序的方法:1. LINQ链式调用:使用OrderBy和ThenBy实现多级排序,直观易读,适合动态需求,返回新列表。2. 自定义比较器(IComparer):适用于复杂或高频排序&#…...
C++初阶-vector的模拟实现3
目录 1.预备知识:initializer_list 1.1初步了解 1.2关于initializer_list的deepseek的回答 C中的 std::initializer_list 主要特性 常见用途 1. 接受列表的构造函数和函数 2. 基于范围的 for 循环 重要注意事项 实现示例 2.vector::vector(initializer_li…...
详解鸿蒙仓颉开发语言中的日志打印问题
一门新的开发语言在诞生初期,由于它本身的特性和使用人数暂时较少,会容易出现一些大家不太容易理解的问题,或者说有一些坑。今天就详细分享一下仓颉开发语言中的日志打印相关内容,带大家踩一踩坑。 AppLog 在新创建的项目中&…...
dify基于文本模型实现微调Fine-tune语料构造工作流
主要是分为5个部分。分别是:开始、文档提取器、代码执行、LLM大语言模型、结束 5个部分 打开dify,创建一个空白页面-选择工作流,我们给应用起个名字。 创建完成后,进入工作流画布界面 开始 在开始节点中新建2个输入参数。1个是用…...
手机充电协议
1、手机快充 公有:PD、QC(高通骁龙芯片) 私有: 华为:FCP(fast charge protocol) 、SCP( super charge protocol) 、 小米: Mi Turbo Charge oppo:VOOC/SuperVOOC vivo:FlashCharge、…...
HarmonyOS 应用开发,如何引入 Golang 编译的第三方 SO 库
本指南基于笔者临时修复的 ohos_golang_go 项目fork,解决HO 应用导入 cgo编译产物时的 crash 问题。 1. 下载 ohos_golang_go git clone https://gitcode.com/deslord/ohos_golang_go.git📌 该仓库为笔者临时修复版本,修复了 CGO 编译模式下…...
polarctf-web-[某函数的复仇]
考点: 匿名构造函数(create_function) 题目来源:polarctf-web-[某函数的复仇] 解题: 代码审计: <?phphighlight_file(__FILE__);//flag:/flagif(isset($_POST[shaw])){$shaw $_POST[shaw];$root $_GET[root];if(preg_mat…...
Node.js Express 项目现代化打包部署全指南
Node.js Express 项目现代化打包部署全指南 一、项目准备阶段 1.1 依赖管理优化 # 生产依赖安装(示例) npm install express mongoose dotenv compression helmet# 开发依赖安装 npm install nodemon eslint types/node --save-dev1.2 环境变量配置 /…...
华为云Flexus+DeepSeek征文|Flexus云服务器Dify-LLM资源部署极致体验Agent
前引:重磅来袭!本次以DeepSeek-V3/R1商用大模型和Dify-LLM应用平台一键部署为核心,专为新手打造“开箱即用”的AI开发体验。无论你是想快速搭建企业级AI应用,还是探索大模型落地的无限可能,只需跟随小编实现三步走&…...
Java详解LeetCode 热题 100(18):LeetCode 73. 矩阵置零(Set Matrix Zeroes)详解
文章目录 1. 题目描述2. 理解题目3. 解法一:使用两个额外数组标记法3.1 思路3.2 Java代码实现3.3 代码详解3.4 复杂度分析3.5 适用场景 4. 解法二:使用矩阵的第一行和第一列作为标记4.1 思路4.2 Java代码实现4.3 代码详解4.4 复杂度分析4.5 适用场景 5. …...
MySQL刷题 Day08
LC 1341电影评分 本题思路简单,但一不注意就错了 : 不难想到用union,写出如下代码: (select u.name results from MovieRating mr left join Users u on mr.user_id u.user_id group by mr.user_id order by count(mr.user_id…...
linux查看本机服务器的外网IP命令
在 Linux 中查看本机服务器的外网 IP(公网 IP)可以通过以下几种方法: 1. 使用 curl 查询外部服务(推荐) curl ifconfig.me或: curl icanhazip.com或: curl ipinfo.io/ip这些服务会返回你的公…...
DVWA-XSS
DOM low 这是一个下拉框的形式,但是如果我们不让他等于English呢,换成js代码呢? <script>alert(xss);</script> Medium <script> 标签,但仅使用简单的字符串匹配进行替换(比如移除 "<scr…...
第15天-NumPy科学计算实战:从基础到图像处理
一、NumPy核心优势 高效数组运算:矢量操作比纯Python快10-100倍 广播机制:不同形状数组的算术运算 内存优化:连续内存块存储,支持大数据处理 丰富API:线性代数、傅里叶变换、随机数生成等 二、环境准备 pip install numpy matplotlib 三、基础操作演示 1. 创建数组 im…...
Spring Boot + +小程序, 快速开发零工市场小程序
现在零工经济发展的越来越好,不止是很多人想要利用空余时间找零工赚外快,也有很多企业有灵活用工的需求,根据这样的需求,我们利用Spring Boot 和小程序,快速开发出了零工市场小程序。 利用 Spring Boot 开发零工市场小…...
Vue 3.0中核心的Composition API
在当今快速发展的前端生态系统中,Vue 3.0以其革命性的Composition API重新定义了组件开发的范式。作为Vue框架的一次重大进化,Composition API不仅解决了Options API在复杂组件中面临的逻辑复用和组织难题,更为开发者提供了更灵活、更强大的代…...
洛谷B3840 [GESP202306 二级] 找素数
题目描述 小明刚刚学习了素数的概念:如果一个大于 1 的正整数,除了 1 和它自身外,不能被其他正整数整除,则这个正整数是素数。现在,小明想找到两个正整数 A 和 B 之间(包括 A 和 B)有多少个素数…...
Axure设计之带分页的穿梭框原型
穿梭框(Transfer)是一种常见且实用的交互组件,广泛应用于需要批量选择或分配数据的场景。 一、应用场景 其典型应用场景包括: 权限管理系统:批量分配用户角色或系统权限数据筛选工具:在大数据集中选择特…...
VsCode开发环境之Node.js离线部署
1.下载node部署文件 地址为:CNPM Binaries Mirror 2.下载后解压 3.验证版本 4.配置环境变量 5.外网寻找一个对应项目的npm文件--node_modules 6.node_modules文件夹复制到node.js的路径下 7.接着就可以正常运行了。...
补充Depends 和 request: Request 依赖注入用法的注意事项
不要在非路由函数(如类的 __init__ 方法或普通模块函数)中直接使用 Depends() 或 request。 Depends 和 request: Request 是 FastAPI 提供的依赖注入机制的一部分,仅适用于FastAPI 路由函数或由 FastAPI 调用的依赖函数中。在类初始化、模块…...
uniapp-商城-64-后台 商品列表(商品修改---页面跳转,深浅copy应用,递归调用等)
完成了商品的添加和展示,下面的文字将继续进行商品页面的处理,主要为商品信息的修改的页面以及后天逻辑的处理。 本文主要介绍了商品信息修改页面的实现过程。首先,页面布局包括编辑和删除功能,未来还可添加上架和下架按钮。通过c…...
【MySQL】联合查询(上)
目录 一. 什么是联合查询 二. 笛卡尔积 三. 内连接查询 示例演示 四. 外连接 示例演示 五. 自连接 自连接 示例演示 一. 什么是联合查询 在之前学习的增删改查中都是对于单表进行查询,但是因为在数据库设计时需要遵循范式的要求,数据就会被拆分到多…...
Model 是 Agent 的大脑(以camel为例)
Model 是 Agent 的大脑,负责处理所有输入和输出数据。通过有效调用不同的模型,智能体可以根据任务需求执行文本分析、图像识别和复杂推理等操作。CAMEL 提供了一系列标准和可定制的接口,并与各种组件无缝集成,以赋能大语言模型&am…...
Linux条件变量
在 Linux 系统中,pthread_cond_init() 函数和条件变量(Condition Variable)是多线程编程中用于线程同步的核心机制。它们通过协调线程间的等待与通知逻辑,解决共享资源的竞争问题。以下从功能、工作机制、使用场景和注意事项等方面…...
k8s-NetworkPolicy
在 Kubernetes 中,NetworkPolicy 是一种资源对象,用于定义 Pod 之间的网络通信策略。它允许你控制哪些 Pod 可以相互通信,以及如何通信。通过使用 NetworkPolicy,可以实现更细粒度的网络访问控制,增强集群的安全性。 1…...
什么是“架构孤岛”?如何识别与整合?为什么现代企业在追求敏捷开发的同时,反而更容易陷入架构孤岛陷阱?
在现代信息技术飞速发展的时代,系统架构日益复杂,组织在构建与演进其信息系统时,面临着前所未有的挑战。然而,就在不断追求敏捷性、可扩展性与数字化创新的过程中,一个被广泛忽视却日益严峻的问题悄然浮现——“架构孤岛”。它们像岛屿一样,彼此孤立,通信不畅,数据难以…...
nfs存储IO等待,导致k8s业务系统卡慢问题处理
注:服务器配置:64C,128G,麒麟v10系统,系统磁盘使用空间(5T)均低于50%,存储磁盘iops约为800左右 发现业务系统卡慢,使用top 命令查看.系统负载较高长期保持在60以上,发现wa值的指标参数长期高于15,返现CPU用于写入磁盘IO等待的时间较高,系统的磁盘I/O压力较大. 配合开发查看日志…...
如何使用两块硬盘作为 Ubuntu24 的系统盘,实现坏掉一块不影响系统运行。
最近我想使用Ubuntu组一个NAS系统,想实现系统盘冗余,各位大佬可以给点建议吗。 Deep Seek 为了实现两块硬盘作为 Ubuntu 24 系统盘的冗余配置(RAID 1),确保一块硬盘损坏时系统仍可运行,以下是详细步骤&am…...
电子电气架构 --- 细化造车阶段流程
我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 钝感力的“钝”,不是木讷、迟钝,而是直面困境的韧劲和耐力,是面对外界噪音的通透淡然。 生活中有两种人,一种人格外在意别人的眼光;另一种人无论…...
物联网之使用Vertx实现UDP最佳实践【响应式】
小伙伴们,你们好呀,我是老寇,跟我一起学习使用Vertx实现UDP-Server 实现UDP【响应式】 Vertx-Core地址 注意 UDP是无连接的传输,这意味着您与远程客户端没有建立持续的连接。 所以,您发送和接收的数据包都要包含有…...
代码管理平台Gitlab如何通过快解析实现远程访问?
一、Gitlab功能介绍 Gitlab是被广泛使用的基于git的开源代码管理平台,用于管理、存储开发人员代码,同时可以协同开发 二、外网试用Gitlab遇到的问题 运维人员将Gitlab服务器部署在总部机房,而分公司开发人员和出差运维人员就无法访问Gitlab…...
七彩喜防摔马甲:科技守护银发安全的“隐形铠甲”
随着现代人生活方式的多样化,尤其是在户外运动和骑行等活动中,安全问题日益受到重视。 七彩喜防摔马甲,作为一款兼具防护性与舒适性的智能穿戴设备,正在改变人们对传统防护装备的认知。 创新设计 防摔马甲的设计灵感来源于人体…...
IDEA推送到gitlab,jenkins识别,然后自动发布到需要的主机
实验环境 192.168.8.100 gitlab 192.168.8.200 jenkins mvn 192.168.8.10 测试主机 默认都关闭了防火墙和setenforce 实验要求 实验在IDEA上面推送代码然后gitlab推送给jenkins,然后mvn构建,最后发布到测试主机上面 实验开始 在tomcat上安装manve…...
五、【API 开发篇(下)】:使用 Django REST Framework构建测试用例模型的 CRUD API
【API 开发篇】:使用 Django REST Framework构建测试用例模型的 CRUD API 前言第一步:增强 Serializers (序列化器) - 处理关联和选择项第二步:创建 TestCaseViewSet (视图集) - 支持过滤第三步:注册 TestCaseViewSet 到 Router第…...
IDEA推送到gitlab,jenkins识别,然后自动发布到需要的主机(流水线)
jenkins流水线 新建项目 找到流水线选择脚本 3.点击流水线语法开始编辑脚本 4.生成流水线脚本复制 5.修改脚本 6.继续添加(手打) 7.继续生成添加 8.最终脚本 9.保存测试 10.构建 11.访问主页查看是否修改...
四、【API 开发篇 (上)】:使用 Django REST Framework 构建项目与模块 CRUD API
【API 开发篇 】:使用 Django REST Framework 构建项目与模块 CRUD API 前言为什么选择 Django REST Framework (DRF)?第一步:创建 Serializers (序列化器)第二步:创建 ViewSets (视图集)第三步:配置 URLs (路由)第四步…...
vscode连接本地Ubuntu
因为在学习项目的时候,自己的云服务器性能太差一直要编译很长时间,而且总是连接失败,所以搞了一个Ubuntu25.04的系统在自己的vmare中。 其中参考了以下文章。 Ubuntu 24.04 桌面版安装指南(2025版) | 官网镜像下载启动盘制作保姆级图文教程…...
idea无法识别Maven项目
把.mvn相关都删除了 导致Idea无法识别maven项目 或者 添加导入各个模块 最后把父模块也要导入...
Redis应用--缓存
目录 一、什么是缓存 1.1 二八定律 二、使用Redis作为缓存 三、缓存的更新策略 3.1 定期更新 3.2 实时生成 四、缓存预热、缓存穿透、缓存雪崩和缓存击穿 4.1 缓存预热 4.2 缓存穿透 4.3 缓存雪崩 4.4 缓存击穿 一、什么是缓存 缓存(cache)是计算机的一个经典的概念…...
大语言模型与人工智能:技术演进、生态重构与未来挑战
目录 技术演进:从专用AI到通用智能的跃迁核心能力:LLM如何重构AI技术栈应用场景:垂直领域的技术革命生态关系:LLM与AI技术矩阵的协同演进挑战局限:智能天花板与伦理困境未来趋势:从语言理解到世界模型1. 技术演进:从专用AI到通用智能的跃迁 1.1 三次技术浪潮的跨越 #me…...
多模态大语言模型arxiv论文略读(八十六)
EVALALIGN: Supervised Fine-Tuning Multimodal LLMs with Human-Aligned Data for Evaluating Text-to-Image Models ➡️ 论文标题:EVALALIGN: Supervised Fine-Tuning Multimodal LLMs with Human-Aligned Data for Evaluating Text-to-Image Models ➡️ 论文作…...
C++--string类对象
一,引言 string类对象在于更好的处理字符串问题,为对于字符串这一类型提供更加方便的接口和运算符的重载。本片文章首先会引入auto关键字和范围for两个C11小语法。之后按照如下网站所提供的顺序经行讲解。cplusplus.com - The C Resources Networkhttps://legacy.c…...
云计算与大数据进阶 | 28、存储系统如何突破容量天花板?可扩展架构的核心技术与实践—— 分布式、弹性扩展、高可用的底层逻辑(下)
在上篇中,我们围绕存储系统可扩展架构详细探讨了基础技术原理与典型实践。然而,在实际应用场景中,存储系统面临的挑战远不止于此。随着数据规模呈指数级增长,业务需求日益复杂多变,存储系统还需不断优化升级࿰…...
Python _day31
DAY 31 文件的规范拆分和写法 今日的示例代码包含2个部分 notebook文件夹内的ipynb文件,介绍下今天的思路项目文件夹中其他部分:拆分后的信贷项目,学习下如何拆分的,未来你看到的很多大项目都是类似的拆分方法 知识点回顾 规范的文…...