用C语言写一个自己的shell-Part Ⅱ--execute commands
Part Ⅱ–execute commands
Exec
This brings us to the exec family of functions. Namely, it has the following functions:
execlexecvexecleexecveexeclpexecvp
For our needs,we will use execvp whose signature looks like this
int execvp(const char *file, char *const argv[]);
execvp function indicates that,it accepts the name of a file,for which it will search for $PATH variable of the system and an array of arguments to be executed.
A few things to note about the execvp function:
- The first argument is the name of the command
- The second argument consists of the name of the command and the arguments passed to the command itself. It must also be terminated by
NULL. - It also swaps out the current process image with that of the command being executed, but more on that later.
execvp.c
#include <unistd.h>int main() {char *argv[] = {"ls","-l","-h","-a",NULL};execvp(argv[0],argv);return 0;
}
If you compile and execute the execvp.c, you will see an output similar to the following:
total 32K
drwxrwxr-x 2 marco marco 4.0K 3月 1 22:07 .
drwxrwxr-x 5 marco marco 4.0K 3月 1 22:04 ..
-rwxrwxr-x 1 marco marco 17K 3月 1 22:07 execvp
-rw-rw-r-- 1 marco marco 123 3月 1 22:07 execvp.c
Which is exactly the same if you manually executels -l -h -a
readline
https://tiswww.case.edu/php/chet/readline/rltop.html
With execvp function,we can perform commands in $PATH but how to accept the string of commands as stdin?
This brings us to the Readline Library.
#include <stdio.h>
#include <readline/readline.h>
char * readline (const char *prompt);
However,when I used this function,error occured.
Ubuntu that I used doesn’t have the library by default.Hence,the library need to be installed.
sudo apt-get install libreadline-dev
Meanwhile,we should add an another argument to link the library when compiling the File.c ,otherwise you may see an error like
“undefined reference to `readline’
collect2: error: ld returned 1 exit status”.
gcc File.c -o File -lreadline
And here’s the code.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <readline/readline.h>
#include <sys/wait.h>char **get_input(char *);int main() {//in C,ptr can be used as array.char **command;char *input;pid_t child_pid;int stat_loc;while(1) {input = readline("mysh> ");//with "mysh> " to be a prompt,the function reads a line of input.command = get_input(input);if(!command[0]) {//empty commandsfree(input);free(command);continue;}child_pid = fork();if(child_pid == 0) {//child processexecvp(command[0],command);} else {waitpid(child_pid, &stat_loc, WUNTRACED);}free(input);free(command);}return 0;
}char **get_input(char *input) {char **command = malloc(8 * sizeof(char *));char *separator = " ";char *parsed;int index = 0;parsed = strtok(input, separator);while (parsed != NULL) {command[index] = parsed;index++;parsed = strtok(NULL, separator);}command[index] = NULL;return command;
}
Let’s test it.

However,the exec family of function can’t perform built-in commands like cd.

The code with weak robustness should be revised to be more robust and stronger.
-
Dynamic memory allocation - in
char ** get_input(char *input);The command variable only malloc 8 sizeof(char *).It’s limited,
so you will see the following error:

To handle the error,commandshould malloc dynamic memories.
-
fork failed - If the OS runs out of memory or reaches the maxmum number of allowed processes,a child process will not be created.We add the following segment to our code:
if(child_pid < 0) {perror(command[0]);exit(1);} -
exev failed - the exev function may fail.We modify the following block to our code:
//child processif (execvp(command[0], command) < 0) {perror(command[0]);exit(1);}
The revised code is here,written by chatGPT.The AI is amazing!!!
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <readline/readline.h>
#include <sys/wait.h>char **split_input(char *);int main() {//in C,ptr can be used as array.char **command;char *input;pid_t child_pid;int stat_loc;while(1) {input = readline("mysh> ");//with "mysh> " to be a prompt,the function reads a line of input.command = split_input(input);if(!command[0]) {//empty commandsfree(input);free(command);continue;}//fork failed.child_pid = fork();if(child_pid < 0) {perror(command[0]);exit(1);}if(child_pid == 0) {//child processif (execvp(command[0], command) < 0) {perror(command[0]);exit(1);}} else {waitpid(child_pid, &stat_loc, WUNTRACED);}free(input);free(command);}return 0;
}
char **split_input(char *input) {int capacity = 10;char **command = malloc(capacity * sizeof(char *));if (command == NULL) {fprintf(stderr, "Error: memory allocation failed\n");exit(EXIT_FAILURE);}char *token = strtok(input, " ");int i = 0;while (token != NULL) {if (i == capacity - 1) { // resize the array if it is fullcapacity *= 2;char **new_command = realloc(command, capacity * sizeof(char *));if (new_command == NULL) {fprintf(stderr, "Error: memory allocation failed\n");exit(EXIT_FAILURE);}command = new_command;}command[i] = malloc((strlen(token) + 1) * sizeof(char));if (command[i] == NULL) {fprintf(stderr, "Error: memory allocation failed\n");exit(EXIT_FAILURE);}strcpy(command[i], token);token = strtok(NULL, " ");i++;}command[i] = NULL; // terminate the array with NULLreturn command;
}
相关文章:
用C语言写一个自己的shell-Part Ⅱ--execute commands
Part Ⅱ–execute commands Exec This brings us to the exec family of functions. Namely, it has the following functions: execlexecvexecleexecveexeclpexecvp For our needs,we will use execvp whose signature looks like this int execvp(const char *file, cha…...
案例实践|运营腾讯游戏,Proxima Beta 使用 Apache Pulsar 升级团队协作与数据治理...
文章摘要本文整理自 Pulsar Summit Asia 2022 上,Proxima Beta 软件工程师施磊的分享《How to achieve better team integration and data governance by using Apache Pulsar》。本文首先将为大家介绍 CQRS 和 Event Sourcing 概念,便于了解为何 Proxim…...
Hudi的7种索引
1、Bloom Index Bloom Index (default) 使用根据记录键构建的bloom过滤器,也可以使用记录键范围修剪候选文件.原理为计算RecordKey的hash值然后将其存储到bitmap中,为避免hash冲突一般选择计算3次 HoodieKey 主键信息:主要包含recordKey 和p…...
Linux内核(十三)系统软中断 software
文章目录中断概述Linux内核中断软中断相关代码解析软中断结构体软中断类型软中断两种触发方式函数__do_softirq解析定时器的软中断实现解析定时器相关代码总结Linux版本:linux-3.18.24.x 中断概述 中断要求 快进快出,提高执行效率,…...
Linux -- 查看进程 PS 命令 详解
我们上篇介绍了, Linux 中的进程等概念,那么,在Linux 中如何查看进程呢 ??我们常用到的有两个命令, PS 和 top 两个命令,今天先来介绍下 PS 命令~!PS 命令 :作用 &#x…...
C2科一考试道路通行规定
目录 低能见度等恶劣环境下的通行规定 驾驶机动车禁止行为 停车规定 通行常识 高速公路限速规定 三观不一样的人,无论重来多少次,结果都一样 他不会懂你的委屈 只是觉得自已没错 两个人真正的可悲连吵架都不在一个点上 有句话说得好 我要是没点自我…...
进程概念(详细版)
进程的概念本文主要介绍进程的相关知识 文章目录认识冯诺依曼体系结构操作系统的基本概念操作系统的作用是什么系统调用和库函数相关概念进程基本概念描述进程进程控制块(PCB)task_struct 结构体进程是如何被操作系统管理起来的先描述再组织描述好,组织好࿰…...
学习大数据应该掌握哪些技能
想要了解大数据开发需要掌握哪些技术,不妨先一起来了解一下大数据开发到底是做什么的~ 1、什么是大数据? 关于大数据的解释,比较官方的定义是指无法在一定时间范围内用常规软件工具进行捕捉、管理和处理的数据集合,是需要新处理模…...
【spring】Spring Data --Spring Data JPA
Spring Data 的委托是为数据访问提供熟悉且符合 Spring 的编程模型,同时仍保留着相关数据存储的特殊特征。 它使使用数据访问技术、关系和非关系数据库、map-reduce 框架和基于云的数据服务变得容易。这是一个伞形项目,其中包含许多特定于给定数据库…...
mysql数据库之视图
视图(view)是一种虚拟的存在,视图中的数据并不在数据库中实际存在,行和列数据来自定义视图的查询中使用的表,并且是在使用视图时动态生成的。 通俗的讲,视图之保存了查询的sql逻辑,不保存查询结…...
数据库事务详解
概述事务就是数据库为了保证数据的原子性,持久性,隔离性,一致性而提供的一套机制, 在同一事务中, 如果有多条sql执行, 事务可以确保执行的可靠性.数据库事务的四大特性一般来说, 事务是必须满足 4 个条件(ACID):原子性(Atomicity&…...
Nessus: 漏洞扫描器-网络取证工具
Nessue 要理解网络漏洞攻击,应该理解攻击者不是单独攻击,而是组合攻击。因此,本文介绍了关于Nessus历史的研究,它是什么以及它如何与插件一起工作。研究了Nessus的特点,使其成为网络取证中非常推荐的网络漏洞扫描工具…...
操作系统实战45讲之现代计算机组成
我以前觉得计算机理论不让我感兴趣,而比较喜欢实践,即敲代码,现在才发现理论学好了,实践才能有可能更顺利,更重要的是理论与实践相结合。 在现代,几乎所有的计算机都是遵循冯诺依曼体系结构,而遵…...
Simple Baselines for Image Restoration
Abstract.尽管近年来在图像恢复领域取得了长足的进步,但SOTA方法的系统复杂性也在不断增加,这可能会阻碍对方法的分析和比较。在本文中,我们提出了一个简单的基线,超过了SOTA方法,是计算效率。为了进一步简化基线&…...
Python数据可视化:局部整体图表可视化(基础篇—6)
目录 1、饼图 2、圆环图 3、马赛克图 4、华夫饼图 5、块状/点状柱形图 在学习本篇博文之前请先看一看之前发过的关联知识:...
CSDN新星计划新玩法、年度勋章挑战赛开启
文章目录🌟 写在前面🌟 逐步亮相的活动🌟 勋章挑战赛🌟 新星计划🌟 有付费课程才可参与?🌟 成就铭牌🌟 博客跟社区的关系🌟 写在最后🌟 写在前面 哈喽&#…...
Docker之部署Mysql
通过docker对Mysql进行部署。 如果没有部署过docker,看我之前写的目录拉取镜像运行容器开放端口拉取镜像 前往dockerHub官网地址,搜索mysql。 找到要拉取的镜像版本,在tag下找到版本。 拉取mysql镜像,不指定版本数,…...
基于C/C++获取电脑网卡的IP地址信息
目录 前言 一、网卡是什么? 二、实现访问网卡信息 1.引入库及相关的头文件 2.操作网卡数据 3. 完整代码实现 4.结果验证 总结 前言 简单示例如何在windows下使用c/c代码实现 ipconfig/all 指令 提示:以下是本篇文章正文内容,下面案例可供参考…...
28相似矩阵和若尔当标准型
一、关于正定矩阵的一些补充 在此之前,先讲一下对称矩阵中那些特征值为正数的矩阵,这样特殊的矩阵称为正定矩阵。其更加学术的定义是: SSS 是一个正定矩阵,如果对于每一个非零向量xxx,xTSx>0x^TSx>0xTSx>0 正…...
springboot操作MongoDB
启动类及配置import com.mongodb.client.MongoClient;import com.mongodb.client.MongoClients;import com.mongodb.client.internal.MongoClientImpl;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplicatio…...
古戏台构件声学特性的时域有限差分方法【附模型】
✨ 长期致力于时域有限差分法、窑洞、戏台、八字墙、共形技术研究工作,擅长数据搜集与处理、建模仿真、程序编写、仿真设计。 ✅ 专业定制毕设、代码 ✅ 如需沟通交流,点击《获取方式》 (1)曲面共形网格快速生成算法: …...
echarts中heatmap鼠标滚动禁用缩放,向下滚动
配置如下效果如下...
3分钟掌握HashCalculator:你的文件完整性守护专家
3分钟掌握HashCalculator:你的文件完整性守护专家 【免费下载链接】HashCalculator 哈希值计算工具,批量计算/批量校验/查找重复文件/改变哈希值等,支持集成到系统右键菜单 项目地址: https://gitcode.com/gh_mirrors/ha/HashCalculator …...
别再只测accuracy!DeepSeek集成测试必须监控的5个隐性指标(P99首token延迟、context bleed率、tool-call schema漂移)
更多请点击: https://intelliparadigm.com 第一章:DeepSeek集成测试的核心范式演进 DeepSeek大模型的工程化落地对集成测试提出了全新挑战:传统基于接口响应码与字段校验的测试范式已难以覆盖语义一致性、推理链鲁棒性、上下文敏感度等高阶质…...
为内部知识库问答机器人接入Taotoken多模型增强回答效果
🚀 告别海外账号与网络限制!稳定直连全球优质大模型,限时半价接入中。 👉 点击领取海量免费额度 为内部知识库问答机器人接入Taotoken多模型增强回答效果 构建一个高效的企业内部知识库问答机器人,核心挑战在于如何让…...
智能体所有权与版权:AI Agent Harness Engineering 创造的作品归谁所有?
1. 标题选项 《AI Agent创作版权迷局破解:从Harness工程原理到所有权划分的完整指南》 《智能体作品归谁?AI Agent Harness Engineering场景下的版权规则深度拆解》 《告别权属纠纷:一文搞懂AI Agent生成内容的所有权、版权与收益分配规则》 《Harness工程视角下的AI创作权:…...
基于Arduino的智能蓝调节拍器:DIY音乐练习伴侣
1. 项目概述:一个能“演奏”蓝调的低成本节拍器玩乐器的人,对节拍器这东西又爱又恨。它像一位严厉的监工,用单调的“嘀嗒”声强迫你跟上节奏。但你想过没有,这个监工其实可以很有趣?几年前,我在练习蓝调吉他…...
Unity动态自然系统:Forest Environment-Dynamic Nature深度解析
1. 这不是“贴图堆砌”,而是自然系统级建模:Forest Environment-Dynamic Nature 的真实定位你有没有试过在Unity里拖进几棵树、铺点草、加个天空盒,然后发现场景像一张静止的风景明信片——风不动、叶不摇、雨不落、雾不散?我做过…...
CentOS 8.5最小化安装后,这5个必做的安全与效率优化设置(附一键脚本)
CentOS 8.5最小化安装后的5个必做安全与效率优化刚完成CentOS 8.5最小化安装的系统就像一张白纸——干净但缺乏生产力。作为运维老手,我见过太多人跳过基础优化直接部署应用,结果在后续使用中频繁遇到权限混乱、软件安装慢、SSH爆破等问题。本文将分享我…...
基于Max78000与规则引导的音频数据集构建:边缘AI声音识别实战
1. 项目概述:当边缘AI遇见棕榈树里的“窃听者”在边缘计算和物联网设备大行其道的今天,我们常常面临一个核心矛盾:一方面,我们希望设备足够“聪明”,能实时识别并响应特定的声音模式,比如工厂里高压阀门的异…...
