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

2024-06-18 21:12

本文主要是介绍【Linux】自定义shell(命令行解释器),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

原理: 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 否0if(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.cgcc -o $@ $^ 
.PHONY:cleanrm -f myshell

演示结果如下

这篇关于【Linux】自定义shell(命令行解释器)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1073067

相关文章

linux hostname设置全过程

《linuxhostname设置全过程》:本文主要介绍linuxhostname设置全过程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录查询hostname设置步骤其它相关点hostid/etc/hostsEDChina编程A工具license破解注意事项总结以RHE

Linux中压缩、网络传输与系统监控工具的使用完整指南

《Linux中压缩、网络传输与系统监控工具的使用完整指南》在Linux系统管理中,压缩与传输工具是数据备份和远程协作的桥梁,而系统监控工具则是保障服务器稳定运行的眼睛,下面小编就来和大家详细介绍一下它... 目录引言一、压缩与解压:数据存储与传输的优化核心1. zip/unzip:通用压缩格式的便捷操作2.

Linux中SSH服务配置的全面指南

《Linux中SSH服务配置的全面指南》作为网络安全工程师,SSH(SecureShell)服务的安全配置是我们日常工作中不可忽视的重要环节,本文将从基础配置到高级安全加固,全面解析SSH服务的各项参... 目录概述基础配置详解端口与监听设置主机密钥配置认证机制强化禁用密码认证禁止root直接登录实现双因素

sqlite3 命令行工具使用指南

《sqlite3命令行工具使用指南》本文系统介绍sqlite3CLI的启动、数据库操作、元数据查询、数据导入导出及输出格式化命令,涵盖文件管理、备份恢复、性能统计等实用功能,并说明命令分类、SQL语... 目录一、启动与退出二、数据库与文件操作三、元数据查询四、数据操作与导入导出五、查询输出格式化六、实用功

在Linux终端中统计非二进制文件行数的实现方法

《在Linux终端中统计非二进制文件行数的实现方法》在Linux系统中,有时需要统计非二进制文件(如CSV、TXT文件)的行数,而不希望手动打开文件进行查看,例如,在处理大型日志文件、数据文件时,了解... 目录在linux终端中统计非二进制文件的行数技术背景实现步骤1. 使用wc命令2. 使用grep命令

Java实现自定义table宽高的示例代码

《Java实现自定义table宽高的示例代码》在桌面应用、管理系统乃至报表工具中,表格(JTable)作为最常用的数据展示组件,不仅承载对数据的增删改查,还需要配合布局与视觉需求,而JavaSwing... 目录一、项目背景详细介绍二、项目需求详细介绍三、相关技术详细介绍四、实现思路详细介绍五、完整实现代码

一文详解Java Stream的sorted自定义排序

《一文详解JavaStream的sorted自定义排序》Javastream中的sorted方法是用于对流中的元素进行排序的方法,它可以接受一个comparator参数,用于指定排序规则,sorte... 目录一、sorted 操作的基础原理二、自定义排序的实现方式1. Comparator 接口的 Lam

Linux如何快速检查服务器的硬件配置和性能指标

《Linux如何快速检查服务器的硬件配置和性能指标》在运维和开发工作中,我们经常需要快速检查Linux服务器的硬件配置和性能指标,本文将以CentOS为例,介绍如何通过命令行快速获取这些关键信息,... 目录引言一、查询CPU核心数编程(几C?)1. 使用 nproc(最简单)2. 使用 lscpu(详细信

linux重启命令有哪些? 7个实用的Linux系统重启命令汇总

《linux重启命令有哪些?7个实用的Linux系统重启命令汇总》Linux系统提供了多种重启命令,常用的包括shutdown-r、reboot、init6等,不同命令适用于不同场景,本文将详细... 在管理和维护 linux 服务器时,完成系统更新、故障排查或日常维护后,重启系统往往是必不可少的步骤。本文

shell中set -u、set -x、set -e的使用

《shell中set-u、set-x、set-e的使用》本文主要介绍了shell中set-u、set-x、set-e的使用,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参... 目录✅ 1. set -u:防止使用未定义变量 作用: 示例:❌ 报错示例输出:✅ 推荐使用场景:✅ 2. se