【Linux】自定义shell(命令行解释器)

news2024/11/24 6:04:47

原理: shell是命令行解释器,当有命令需要执行时,shell创建子进程,让子进程执行命令,而shell只需等待子进程退出即可。

其中我们使用了下面这几个函数:

  • 获取命令行(fgets函数)。
  • 解析命令行(strtok分割字符串)。
  • 创建子进程(fork函数)。
  • 替换子进程(exec函数族)。
  • 等待子进程退出(waitpid函数)

 实现简易命令解释行的过程中我们遇到了一些问题:

cd,export等內键命令,在子进程下修改无法影响到bash,所以我们增加了函数来判断命令是否为內键命令,并判断其是否为空,使用chdir修改其所在路径通过argv[1]取出要到的路径。

但是我们发现如果进入的是..  上级路径的话 就会变成下面这样

 

我们的目录名称直接变成了..,此时我们需要使用 snprintf函数 将temp写入pwd中。

以下为简易实现的代码

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<sys/wait.h>
#include<sys/types.h>
#define SIZE 1024
#define MAX_ARGC 64
#define SEP " "
char *argv[MAX_ARGC];
char PWD[SIZE];
 const char* HostName()
 {
    char *hostname=getenv("HOSTNAME");
    if(hostname) return hostname;
    else return "none";
 }
 const char* UserName()                       
 {                                            
   char *hostname=getenv("USER");         
   if(hostname) return hostname;              
   else return "none";                        
 }         
 const char* CurrentWorkDir()   
 {                    
   char *hostname=getenv("PWD");         
   if(hostname) return hostname;              
   else return "none";                        
 }  
 char *Home()
 {
   return getenv("HOME");
 }
 int Interactive(char out[],int size)
 {
                                                                                                                                                                                                   
   printf("[%s@%s %s]$",UserName(),HostName(),CurrentWorkDir());
   fgets(out,size,stdin);
   out[strlen(out)-1]=0;//'\0'
   return strlen(out);
 }
void Split(char in[])
 {
   int i=0;
   argv[i++]=strtok(in,SEP);
     while(argv[i++]=strtok(NULL,SEP));
 }
 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 BuildinCmd()
 {
   int ret=0;
   //1.检测是否为内建命令 是1 否0
   if(strcmp("cd",argv[0])==0)                                                                                                                                                                     
   {
     ret=1;
     char *target=argv[1];
     if(!target) target=Home();
     chdir(target);
     char temp[1024];
      getcwd(temp,1024);
      snprintf(PWD,SIZE,"PWD=%s",temp);
      putenv(PWD);
  }
   //2.执行
   return ret;
 }
 int main()
 {
  //1.打印命令行提示符,获取用户输入的命令字符串
  while(1)
  {
   char commandline[SIZE];
   int n= Interactive(commandline,SIZE);
   if(n==0) continue;
   //2.对命令行进行切割
   Split(commandline);
   //3.处理内建命令
   n=BuildinCmd();
   if(n) continue;
   //4.执行这个命令
   Execute();
  }
   //int j=0;
   //for(j=0;argv[j];j++)
   //{
   //  printf("argv[%d]: %s\n",j,argv[j]);
   //}
   return 0;
 }                                       

 Makefile文件的配置:

myshell:myshell.c
		gcc -o $@ $^ 
.PHONY:clean
	rm -f myshell

演示结果如下

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1835923.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

MAX30102驱动

文章目录 一、引言二、MAX30102传感器概述2.1 模块原理血氧饱和度&#xff08;SpO2&#xff09;测量原理心率测量原理 2.2 模块工作流程 三、硬件连接四、驱动程序4.1 FIFO介绍4.2 max30102寄存器配置 五、数据采集与处理六、示例项目七、故障排除八、结论九、附录 一、引言 本…

虚拟货币投资指南|XEX交易所

什么是虚拟货币&#xff1f; 虚拟货币是一种基于区块链技术的数字资产&#xff0c;具有去中心化、透明性和安全性等特点。比特币&#xff08;BTC&#xff09;、以太坊&#xff08;ETH&#xff09;和莱特币&#xff08;LTC&#xff09;等是目前较为知名的虚拟货币。 虚拟货币投…

降压开关稳压器如何使用串联晶体管

降压开关稳压器是一种开关模式电源电路&#xff0c;旨在有效地将直流电压从较高电压降低到较低电压&#xff0c;即减去或“降压”电源电压&#xff0c;从而降低输出端可用的电压端子无需改变极性。换句话说&#xff0c;降压开关调节器是降压调节器电路&#xff0c;因此例如降压…

生成对抗网络——GAN深度卷积实现(代码+理解)

本篇博客为 上篇博客的 另一个实现版本&#xff0c;训练流程相同&#xff0c;所以只实现代码&#xff0c;感兴趣可以跳转看一下。 生成对抗网络—GAN&#xff08;代码理解&#xff09; http://t.csdnimg.cn/HDfLOhttp://t.csdnimg.cn/HDfLO 目录 一、GAN深度卷积实现 1. 模型…

苍穹外卖---导入接口文档

一、前后端分离开发流程 第一步&#xff1a;定义接口&#xff0c;确定接口的路径、请求方式、传入参数、返回参数。 第二步&#xff1a;前端开发人员和后端开发人员并行开发&#xff0c;同时&#xff0c;也可自测。 第三步&#xff1a;前后端人员进行连调测试。 第四步&…

搭建zookeeper、Kafka集群

搭建zookeeper、Kafka集群 1、绘制kafka的存储结构、副本机制2、搭建zookeeper集群3、搭建kafka集群4、使用kafka创建名为自己姓名汉语拼音的topic5、查看topic的分区和副本策略 1、绘制kafka的存储结构、副本机制 2、搭建zookeeper集群 实验环境准备&#xff1a; 3台服务器&…

界面追踪方法Level Set与VOF在气泡流动模拟的效果比较

对于两相流模拟&#xff0c;模型主要分为两大类&#xff1a;高相分数模型和界面捕捉类模型。当我们关注水中的含气量&#xff08;气泡界面及气泡形状可忽略&#xff09;&#xff0c;则采用高相分数模型&#xff0c;此模型适用于气泡特别多的流动问题。对于有明确边界的流体&…

AI安全水深流急,黄铁军首谈AGI能力与风险分级,2024智源大会圆满落幕

2024年6月15日&#xff0c;为期 2 天的北京智源大会圆满落下帷幕。本次大会围绕大语言模型、多模态模型、Agent、具身智能、数据新基建、AI系统、AI开源、AI for Science、AI安全等人工智能热门技术方向和焦点议题&#xff0c;召开了20平行论坛&#xff0c;共计百场报告。 过去…

Linux top 命令使用教程

转载请标明出处&#xff1a;https://blog.csdn.net/donkor_/article/details/139775547 文章目录 一、top 是什么二、top的基础语法三、top输出信息解读 一、top 是什么 Linux top 是一个在Linux和其他类 Unix 系统上常用的实时系统监控工具。它提供了一个动态的、交互式的实时…

基于JSP的房屋租赁系统

开头语&#xff1a; 你好&#xff0c;我是专注于计算机科学与技术研究的学长。如果你对房屋租赁系统感兴趣或有相关开发需求&#xff0c;欢迎联系我。 开发语言&#xff1a;Java 数据库&#xff1a;MySQL 技术&#xff1a;JSPJavaBeansServlet 工具&#xff1a;MyEclipse、…

gRPC(Google Remote Procedure Call Protocol)谷歌远程过程调用协议

文章目录 1、gRPC简介2、gRPC核心的设计思路3、gPRC与protobuf关系 1、gRPC简介 gPRC是由google开源的一个高性能的RPC框架。Stubby Google内部的RPC&#xff0c;演化而来的&#xff0c;2015年正式开源。云原生时代是一个RPC标准。 2、gRPC核心的设计思路 网络通信 ---> gPR…

VM4.3 二次开发04 方案输出结果设置

方案输出结果设置&#xff0c;这个设置是为了在二次开发的上位机软件中显示我们想要的数据&#xff0c;和在二开中如何获取这些结果。 打开方案点下如中的图标。 打开如下图。 再点点红色圈出来的图标&#xff0c;打开参数设置界面。 输出设置可以要输出的数据和参数名称。点上…

【Linux】程序地址空间之动态库的加载

我们先进行一个整体轮廓的了解&#xff0c;随后在深入理解细节。 在动态库加载之前还要说一下程序的加载&#xff0c;因为理解了程序的加载对动态库会有更深的理解。 轮廓&#xff1a; 首先&#xff0c;不管是程序还是动态库刚开始都是在磁盘中的&#xff0c;想要执行对应的可…

隧道代理是什么?怎么运作的?

隧道代理作为网络代理的一种形式&#xff0c;已经在现代互联网世界中扮演着重要的角色。无论是保护隐私、访问受限网站还是实现网络流量的安全传输&#xff0c;隧道代理都发挥着重要作用。在本文中&#xff0c;我们将深入探讨隧道代理的概念、运作方式以及在不同场景中的应用。…

ClickHouse 高性能的列式数据库管理系统

ClickHouse是一个高性能的列式数据库管理系统&#xff08;DBMS&#xff09;&#xff0c;主要用于在线分析处理查询&#xff08;OLAP&#xff09;。以下是对ClickHouse的详细介绍&#xff1a; 基本信息&#xff1a; 来源&#xff1a;由俄罗斯的Yandex公司于2016年开源。全称&…

在向量数据库中存储多模态数据,通过文字搜索图片

在向量数据中存储多模态数据&#xff0c;通过文字搜索图片&#xff0c;Chroma 支持文字和图片&#xff0c;通过 OpenClip 模型对文字以及图片做 Embedding。本文通过 Chroma 实现一个文字搜索图片的功能。 OpenClip CLIP&#xff08;Contrastive Language-Image Pretraining&…

Eigen中 Row-Major 和 Column-Major 存储顺序的区别

Eigen中 Row-Major 和 Column-Major 存储顺序的区别 flyfish Eigen::RowMajor 是 Eigen 库中用于指定矩阵存储顺序的一种选项 理解 Row-Major 和 Column-Major 存储顺序的区别&#xff0c;绘制一个单一的图来显示内存中的元素访问顺序,在图中用箭头表示访问顺序. import nu…

【无重复字符的最长子串】

无重复字符的最长字串 一、题目二、解决方法1.暴力解法2.滑动窗口哈希 三、总结1.es6 new set()的用法添加元素add()删除元素delete()判断元素是否存在has 2.滑动窗口和双指针的联系和特点 一、题目 二、解决方法 1.暴力解法 解题思路&#xff1a;使用两层循环逐个生成子字符串…

Ardupilot开源代码之ExpressLRS性能实测方法

Ardupilot开源代码之ExpressLRS性能实测方法 1. 源由2. 测试效果3. 测试配置4. 总结5. 参考资料6. 补充 1. 源由 之前一直在讨论ExpressLRS性能的问题&#xff0c;有理论、模拟、实测。 始终缺乏完整的同一次测试的测试数据集&#xff0c;本章节将介绍如何在Ardupilot上进行获…

聆思CSK6大模型+AI交互多模态开源SDK介绍

视觉语音大模型 AI 开发套件( CSK6-MIX )是围绕 CSK6011A 芯片设计的具备丰富语音图像功能与硬件外设的开发板&#xff0c;采用具备丰富组件生态的 Zephyr RTOS作为操作系统&#xff0c;官方提供了十几种开源SDK&#xff0c;包含大模型语音交互、大模型拍照识图、文生图、人脸识…