【Linux】模拟实现一个简单的minishell

news2024/11/24 13:35:38


目录

从显示屏获取输入字符流

分割字符串 取出命令名称及选项

去除输入时多按的那个换行符

创建子进程,实现程序替换

如果替换失败,进程终止exit

查看子进程情况

实现echo $?功能

实现cd

最终代码


基本思路 让父进程创建一个子进程,由这个子进程进行程序替换。父进程要对这个进程进行追踪、回收。具体实现模块如下:


从显示屏获取输入字符流

 char* s=fgets(buffer,sizeof (buffer)-1,stdin);
    assert(s!=NULL);
    buffer[strlen (buffer)-1]=0;
    (void*)s;

分割字符串 取出命令名称及选项

//切割字符串
    myargv[0]=strtok(buffer," ");
    int i=0;

    if(myargv[0] != NULL && strcmp(myargv[0], "ls") == 0)
    {
      myargv[++i] = (char*)"--color=auto";
    }

    while(myargv[i]!=NULL)
    {
      myargv[++i]=strtok(NULL," ");
    }

创建子进程,实现程序替换

pid_t id =fork();
    if(id==0)
    {
      //子进程
      //程序替换
      execvp(myargv[0],myargv); 
      //如果走到这里表示替换失败
      exit(1);
    }

查看子进程情况

//父进程
   int status=0;
   pid_t ret= waitpid(id,&status,0);
   assert(ret > 0);
   (void)ret;
   quitcode=(status>>8)&0XFF;
   quitsignal= (status & 0x7F);

实现echo $?功能

 //实现echo $?功能
    if(myargv[0]!=NULL&&myargv[1]!=NULL&&strcmp(myargv[0],"echo")==0)
    {
      if(strcmp(myargv[1],"$?")==0)
      {
        //输出上一个进程的退出码
        printf("退出码为:%d\n",quitcode);

      }
      else
      {
        printf("%s\n",myargv[1]);
      }
      continue;

    }

实现cd

 //实现cd功能
    if(myargv[0] != NULL &&strcmp(myargv[0],"cd")==0)
    {
      if(myargv[1]!=NULL)
      {

        chdir(myargv[1]);
      }
      continue;
    }

最终代码

#include<stdio.h>
#include<string.h>
#include<assert.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/wait.h>
#include<stdlib.h>


#define B_NUM 1024
#define ARGV_NUM 10

char buffer[B_NUM];
char* myargv[ARGV_NUM];
int quitcode;
int quitsignal;


int main()
{
  while(1)
  {
    printf("【用户名@服务器 当前目录】$");
    fflush(stdout);

    char* s=fgets(buffer,sizeof (buffer)-1,stdin);
    assert(s!=NULL);
    buffer[strlen (buffer)-1]=0;
    (void*)s;
   
    //切割字符串
    myargv[0]=strtok(buffer," ");
    int i=0;

    if(myargv[0] != NULL && strcmp(myargv[0], "ls") == 0)
    {
      myargv[++i] = (char*)"--color=auto";
    }

    while(myargv[i]!=NULL)
    {
      myargv[++i]=strtok(NULL," ");
    }

    //实现cd功能
    if(myargv[0] != NULL &&strcmp(myargv[0],"cd")==0)
    {
      if(myargv[1]!=NULL)
      {

        chdir(myargv[1]);
      }
      continue;
    }
    //实现echo $?功能
    if(myargv[0]!=NULL&&myargv[1]!=NULL&&strcmp(myargv[0],"echo")==0)
    {
      if(strcmp(myargv[1],"$?")==0)
      {
        //输出上一个进程的退出码
        printf("退出码为:%d\n",quitcode);

      }
      else
      {
        printf("%s\n",myargv[1]);
      }
      continue;

    }

    pid_t id =fork();
    if(id==0)
    {
      //子进程
      //程序替换
      execvp(myargv[0],myargv); 
      //如果走到这里表示替换失败
      exit(1);
    }

   //父进程
   int status=0;
   pid_t ret= waitpid(id,&status,0);
   assert(ret > 0);
   (void)ret;
   quitcode=(status>>8)&0XFF;
   quitsignal= (status & 0x7F);

  }
  return 0;
}

最后

加油

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

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

相关文章

MySQL5.7升级8.0,导入报错

MySQL8中语法和5.7版本有些稍许改动&#xff0c;建议各位导入的时候&#xff0c;可以使用单、多表使用SQL语句导入&#xff0c;不建议全表导入

移动硬盘装系统可以作为启动硬盘吗?装系统后还能恢复数据吗

随着科技的不断发展&#xff0c;移动硬盘已成为我们生活中不可或缺的数据存储工具。然而&#xff0c;除了存储数据&#xff0c;移动硬盘可不可以装系统当启动盘用呢&#xff1f;移动硬盘装系统后还能恢复原来的数据吗&#xff1f;下面文章中将一一为您详细解答。 图片来源于网络…

模仿奈雪Banner组件

components <template><view class"wrap" :style"{height:wrapHeight}"><!--banner的背景 --><view class"wrap__bgSwiper"><image class"wrap__bgSwiper__item" v-for"(item, index) in list"…

解决InputStream流无法重复使用的问题

一.需求 现在有个需求&#xff0c;要通过InputStream流先去判断文件类型&#xff0c;然后再上传文件&#xff0c;这样就会用到两次InputStream。 二.问题 这个功能之前的同事已经做了一版&#xff0c;一直以为是正常的&#xff0c;毕竟都很久了&#xff0c;但是我用的时候发…

【Unity3D小功能】Unity3D中Text使用超链接并绑定点击事件

推荐阅读 CSDN主页GitHub开源地址Unity3D插件分享简书地址我的个人博客 大家好&#xff0c;我是佛系工程师☆恬静的小魔龙☆&#xff0c;不定时更新Unity开发技巧&#xff0c;觉得有用记得一键三连哦。 一、前言 在开发中遇到了要给Text加超链接的需求&#xff0c;研究了实现…

“量子+半导体”!罗姆半导体与量子公司Quanmatic进行应用探索

​内容来源&#xff1a;量子前哨&#xff08;ID&#xff1a;Qforepost&#xff09; 编辑丨慕一 编译/排版丨琳梦 卉可 深度好文&#xff1a;1500字丨10分钟阅读 2023年&#xff0c;日本半导体制造商Rohm&#xff08;罗姆&#xff09;与量子算法解决方案公司Quanmatic达成合作…

【开源精选导航】GitHub-Chinese-Top-Charts:一榜在手,优质中文项目轻松找寻

各位热爱开源技术的朋友们&#xff0c;你们是否有过这样的困扰&#xff1a;面对浩瀚的GitHub海洋&#xff0c;想找寻那些具有高质量中文文档的优秀开源项目却无从下手&#xff1f;今天&#xff0c;我们就为大家揭晓一个宝藏般的开源项目——GitHub 中文项目集合&#xff08;访问…

CSA发布 | 法律视角下的数据出境《2023年数据出境合规年鉴》

在全球数字产业以及大数据和云计算技术快速发展的背景下&#xff0c;数据流动对世界经济的影响日益显著。由此带来的数据红利和数据安全之间的冲突&#xff0c;将对未来数字经济的发展方向产生深刻影响。 2023 年可称为中国数据跨境监管的元年&#xff0c;这一年初出境评估的“…

flask基于python的个人理财备忘录记账提醒系统vue

在当今高度发达的信息中&#xff0c;信息管理改革已成为一种更加广泛和全面的趋势。 “备忘记账系统”是基于Mysql数据库&#xff0c;在python程序设计的基础上实现的。为确保中国经济的持续发展&#xff0c;信息时代日益更新&#xff0c;蓬勃发展。同时&#xff0c;随着信息社…

BPF开发: 从Hello World开始

Part 1 概述 1. 背景 BPF技术被列为近些年Linux内核领域最火热的新领域之一。它成功的给Linux内核赋予了少量的动态可编程性&#xff0c;可以在Linux内核运行时&#xff0c;实时修改内核的行为,但不需要重新编译和重启内核。据此&#xff0c;BPF在Linux世界中: 网络可观测性…

使用.NET6 Avalonia开发跨平台三维应用

本文介绍在Vistual Studio 2022中使用Avalonia和集成AnyCAD Rapid AvaloniaUI三维控件的过程。 0 初始化环境 安装Avalonia.Templates dotnet new install Avalonia.Templates若之前安装过可忽略此步骤。 1 创建项目 选择创建AvaloniaUI项目 选一下.NET6版本和Avalonia版…

ADB的配置和使用及刷机root

ADB的配置和使用 ADB即Android Debug Bridge&#xff0c;安卓调试桥&#xff0c;是谷歌为安卓开发者提供的开发工具之一&#xff0c;可以让你的电脑以指令窗口的方式控制手机。可以在安卓开发者网页中的 SDK 平台工具页面下直接下载对应系统的 adb 配置文件&#xff0c;大小只…

腾讯云0基础10秒搭建幻兽帕鲁游戏联机服务器

幻兽帕鲁&#xff08;Palworld&#xff09;是一款多人在线游戏&#xff0c;为了获得更好的游戏体验&#xff0c;需要搭建一个稳定、高效的游戏联机服务器。腾讯云提供了一种简单、快速的方法&#xff0c;让新手小白也能0基础10秒搭建幻兽帕鲁游戏联机服务器&#xff01; 本文将…

人工视觉仍然需要图像采集卡

最初&#xff0c;图像采集卡被用作模拟视频数字转换器和图像缓冲器&#xff0c;但如今它们能够执行复杂的任务&#xff0c;例如图像处理。图像采集卡的设计不断发展&#xff0c;旨在提高系统性能并减少计算机处理需求。 除了图像采集之外&#xff0c;图像采集卡还执行机器视觉…

【前端-VUE+TS】Vue3组件化-下(五)

一. 插槽的使用 1.1. 认识插槽slot 在开发中&#xff0c;我们会经常封装一个个可复用的组件&#xff1a; 前面我们会通过props传递给组件一些数据&#xff0c;让组件来进行展示&#xff1b;但是为了让这个组件具备更强的通用性&#xff0c;我们不能将组件中的内容限制为固定的d…

如何在Excel中清除单元格的格式?这里有详细步骤

Microsoft Excel提供了大量样式选项来自定义电子表格的外观。但是&#xff0c;如果你需要删除格式&#xff0c;则可以很容易地删除选定单元格和整个工作表的格式。我们将向你展示如何操作。 ​注意&#xff1a;清除格式只会删除文本的样式&#xff1b;将保留你的实际文本。 如…

基于Android的成人教育课程学习考试系统uniAPP的 小程序_12lo1

APP性能需求 &#xff08;1&#xff09;会员在安卓App页面各种操作可及时得到反馈。 &#xff08;2&#xff09;该平台是提供给多个会员使用的平台&#xff0c;会员使用之前需要注册登录。登录验证后&#xff0c;会员才可进行各种操作[10]。 &#xff08;3&#xff09;管理员用…

在线视频链接怎么做成二维码?扫码播放在线视频的制作方法

怎么把在线视频链接做成二维码图片分享给其他人呢&#xff1f;现在通过二维码来传递内容是很多人在用的一种方式&#xff0c;比如文件、视频、音频、网址等都可以用二维码生成器来做成二维码图片后使用。 采用二维码图片的方式可以有效的降低成本&#xff0c;提高传播的速度&a…

马哈鱼SQLFlow Lite的python版本

Gudu SQLFlow 是一款用来分析各种数据库的 SQL 语句和存储过程来获取复杂的数据血缘关系并进行可视化的工具。 Gudu SQLFlow Lite version for python 可以让 python 开发者把数据血缘分析和可视化能力快速集成到他们自己的 python 应用中。 Gudu SQLFlow Lite version for p…

【web | CTF】攻防世界 easyupload

天命&#xff1a;好像也不太easy 目录 步骤一&#xff1a;准备文件 步骤二&#xff1a;上传文件 本条题目有好几个防御点&#xff1a; 后缀名防御&#xff1a;只能上传图片格式内容防御&#xff1a;内容不能有php图片头防御&#xff1a;检测文件的头部信息&#xff0c;是否是…