首页 > 系统相关 >[Linux]简单的shell实现

[Linux]简单的shell实现

时间:2024-11-25 19:57:05浏览次数:7  
标签:shell Linux NULL 简单 进程 myargv include 目录

一个简单的shell实现

什么是内建命令

内建命令是由shell本身提供的命令,而不是通过外部程序(如位于/bin/usr/bin等目录下的可执行文件)来执行的命令。这些命令在shell启动的时候就加载到内存中,执行效率相对较高。

常见的内建命令有:cdpwdecho

什么是当前路径

本质就是进程的工作目录,默认是进程在哪个目录底下执行,它的工作目录就是这个目录。

那这个工作目录可以更改吗?答案是可以的,使用chdir()函数就可以更改当前进程的工作目录。

在我们自己实现一个简单的shell,执行cd命令的时候,你会发现路径没有变化。那是因为在执行命令的时候,我们是使用fork()出来的子进程来执行的cd,子进程有自己的工作目录(一般和父进程的工作目录相同),当执行cd的时候,更改的是子进程的目录,子进程执行完毕,什么都没了,继续用的是父进程,即shell。

简单的shell实现

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

#define NUM 1024
#define OP_NUM 64

char command[NUM];
char *myargv[OP_NUM];
int lastCode = 0;
int lastSig = 0;

int main()
{
    while (1)
    {
        char *user = getenv("USER");
        char *host = getenv("HOSTNAME");
        printf("%s@%s 当前路径#", user, host);
        fflush(stdout);

        char *s = fgets(command, sizeof(command) -1, stdin);//获取命令行的输入
        assert(s != NULL);
        (void)s;
        //清除用户按下的回车
        command[strlen(command) - 1] = 0;

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

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

        //myargv[] 必须以NULL结尾,而strtok函数结束的时候返回NULL
        //strtok()中的NULL表示从上次结束的位置继续查找下一个子串
        while (myargv[i++] = strtok(NULL, " ")) {}

        //不需要创建子进程,让shell自己执行对应的命令
        if (myargv[0] != NULL && strcmp(myargv[0], "cd") == 0)
        {
            if (myargv[1] != NULL) chdir(myargv[1]);
            continue;
        }
        if (myargv[0] != NULL && myargv[1] != NULL && strcmp(myargv[0], "echo") == 0)
        {
            if (strcmp(myargv[1], "$?") == 0) printf("%d, %d\n", lastCode, lastSig);
            else printf("%s\n", myargv[1]);
            continue;
        }
        
        //创建子进程
        pid_t id = fork();
        assert(id != -1);

        if (id == 0)
        {
            //程序替换
            execvp(myargv[0], myargv);
            exit(1);
        }
        int status = 0;
        pid_t ret = waitpid(id, &status, 0);
        assert(ret > 0);
        (void)ret;

        lastCode = WEXITSTATUS(status);
        lastSig = WIFEXITED(status);

    }
}

标签:shell,Linux,NULL,简单,进程,myargv,include,目录
From: https://www.cnblogs.com/wzhiheng/p/18568477

相关文章

  • 嵌入式从入门到入土(Linux1)
    学习目标:认识嵌入式系统常用目录命令:快捷键主要目录结构:路径的概念Linux系统的文件类型通配符学习内容:嵌入式系统是什么?​​​​​​​**专业定义:**嵌入式系统是以应用为中心,基于计算机技术,具备软硬件可裁剪特性,并对功能、可靠性、成本、体积和功耗等有严格要......
  • 常见Linux命令
    1.常见Linux命令Linux命令快查网站https://wangchujiang.com/linux-command/目录切换cd[目录名称]:切换到该目录下的目录cd..(或cd../):切换到上一层目录cd/:切换到系统根目录cd~:切换到用户主目录cd-:切换到上一个操作所在目录目录操作ls:显示目录中的文件和子目录......
  • Linux lspci查看pcie设备速度
    CUDA学习4——如何查看centos系统PCIe带宽(CSDN_0037_20231127)_如何查看服务器pcie带宽-CSDN博客#查看设备idlspci-n#根据设备id查看lspci-nn-s设备id-vv|grep-i'LnkSta:'~#lspci-hlspci:invalidoption--'h'Usage:lspci[<switches>]Basicdisplay......
  • 腾讯通RTX最佳迁移方案,支持移动端与Linux内核国产系统
    一、腾讯通RTX停更带来的核心问题腾讯通RTX停更并下架官网,用户已无法获得后续技术支持或资源下载,同时也迫使用户面临以下无法解决的问题:●无法兼容国产操作系统和移动端:腾讯通RTX的支持范围仅限于Windows和Mac平台,对于日益普及的Linux内核国产操作系统及移动端完全不兼容。●......
  • Linux之CPU缓存
    CPU缓存系统中最快的存储是处理器中的寄存器。但寄存器由于造价比较昂贵,提供的空间也非常有限。因此系统中必须使用存储量大但速度慢的主存(内存)。高速缓存的速度都比主存快。主存的访问时间是8纳秒以上,而缓存的访问时间只有几个CPU时钟周期。在标准的X86平台下,一般有L1L2L3......
  • Linux:fdisk指令
    学习自:fdisk命令详解-知乎Linuxfdisk命令详解:给硬盘分区_fdisk-l-CSDN博客初始化Linux数据盘(fdisk)|华为云_fdisk华为云初始化云盘-CSDN博客1、说明新添加硬盘之后,需要用fdisk指令来完成分区。不要在当前硬盘上使用fdisk,这会删除整个系统。2、用法输入fdisk分区,再输......
  • archlinux 触摸板手势配置
    目录libinput-gestures安装libinput-gestures加入input组创建配置文件可用手势启动libinput-gestures停止libinput-gestures自启动libinput-gesturesTouchpadSynapticssynaptics.4在/etc/X11/xorg.conf.d/目录下会有默认的触摸板配置文件,如果用的libinput,配置文......
  • No toolchains found in the NDK toolchains folder for ABI with prefix: arm-linux-
    一、报错信息二、解决方法1、打开SDKManager,卸载本地NDK。2、然后点击Apply——>OK,重新启动Android工程,成功运行。思想成体系,培养成意识,自律成习惯。我强烈推荐4本可以改变命运的经典著作:《寿康宝鉴》在线阅读白话文《欲海回狂》在线阅读白话文《阴律无情》在线阅......
  • 对GaussDB数据库和数据管理的简单介绍
    一、前言数据库与数据管理有着密切的关系,两者共同构成了一个完整的、可扩展的数据库管理系统。数据库是用于存储数据的系统,为数据提供了安全、可靠、可扩展和可管理的存储环境。随着信息技术的飞速发展,数据已经成为企业的核心资产之一。在这个数据驱动的时代,数据管理成为了企业......
  • Linux下二维码识别库Zbar的安装与使用
    1.安装Zbarsudoapt-getinstalllibzbar-dev2.识别流程读取图像并转换为Zbar内建图像类型创建Zbar扫描器设置扫描参数扫描图像并获取结果#include<zbar.h>//仅能包含该头文件,其他头文件宏定义中写了不可用于使用#include<opencv2/opencv.hpp>usingnamespace......