您的位置:首页 > 教育 > 培训 > 网页升级紧急通知91_厦门百度关键词seo收费_百度收录关键词_南宁seo手段

网页升级紧急通知91_厦门百度关键词seo收费_百度收录关键词_南宁seo手段

2025/5/14 17:10:26 来源:https://blog.csdn.net/2302_80190394/article/details/143255765  浏览:    关键词:网页升级紧急通知91_厦门百度关键词seo收费_百度收录关键词_南宁seo手段
网页升级紧急通知91_厦门百度关键词seo收费_百度收录关键词_南宁seo手段

目录

引言

全局信息

核心代码

核心函数


引言

随着计算机技术的飞速发展,操作系统在人们日常工作和生活中扮演着越来越重要的角色。Linux作为一款开源、自由且功能强大的操作系统,已经成为了众多服务器和开发者的首选平台。Shell作为Linux系统的用户界面,为用户提供了执行命令、管理文件、自动化任务等功能。

在本项目中,我们将实现一个简单的Shell程序——myshell。在myshell中,将模拟shell如何进程执行内建指令、普通指令与进程切换。

全局信息

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>#define LEFT "["
#define RIGHT "]"
#define LABLE "#"
#define DELIM " \t"
#define LINE_SIZE 1024
#define ARGC_SIZE 32
#define EXIT_CODE 44int lastcode = 0;
int quit = 0;
extern char **environ;
char commandline[LINE_SIZE];
char *argv[ARGC_SIZE];
char pwd[LINE_SIZE];// 自定义环境变量表
char myenv[LINE_SIZE];

我们将特定的元素定义为宏,方便代码的理解与阅读。

核心代码

主体分为:指令的交互(打印对话栏,获取指令字符串)

                  指令字符串的拆解

                  判断是否为内建指令

                  不是内建指令,将进行frok执行

                                                在循环中,不断进行交互

int main()
{while(!quit){// 2. 交互问题,获取命令行, ls -a -l > myfile / ls -a -l >> myfile / cat < file.txtinteract(commandline, sizeof(commandline));// commandline -> "ls -a -l -n\0" -> "ls" "-a" "-l" "-n"// 3. 子串分割的问题,解析命令行int argc = splitstring(commandline, argv);if(argc == 0) continue;// 4. 指令的判断 //内键命令,本质就是一个shell内部的一个函数int n = buildCommand(argv, argc);// 5. 普通命令的执行if(!n) NormalExcute(argv);}return 0;
}

核心函数

1.交互


const char *getusername()
{return getenv("USER");
}const char *gethostname()
{return getenv("HOSTNAME");
}void getpwd()
{getcwd(pwd, sizeof(pwd));   //#include <unistd.h>    char* getcwd(char* buf, size_t size);  //buf是一个输出型参数,size是buf的大小,返回值是buf指向的字符串的地址。
}void interact(char *cline, int size)
{getpwd();printf(LEFT"%s@%s %s"RIGHT""LABLE" ", getusername(), gethostname(), pwd);char *s = fgets(cline, size, stdin);assert(s);(void)s;// "abcd\n\0"cline[strlen(cline)-1] = '\0';
}

2.拆解


// ls -a -l | wc -l | head 
int splitstring(char cline[], char *_argv[])
{int i = 0;argv[i++] = strtok(cline, DELIM);while(_argv[i++] = strtok(NULL, DELIM)); // 故意写的=return i - 1;
}

3.普通指令

子进程执行,父进程等待


void NormalExcute(char *_argv[])
{pid_t id = fork();if(id < 0){perror("fork");return;}else if(id == 0){//让子进程执行命令//execvpe(_argv[0], _argv, environ);execvp(_argv[0], _argv);exit(EXIT_CODE);}else{int status = 0;pid_t rid = waitpid(id, &status, 0);if(rid == id) {lastcode = WEXITSTATUS(status);}}
}

4.内建指令


int buildCommand(char *_argv[], int _argc)
{if(_argc == 2 && strcmp(_argv[0], "cd") == 0){chdir(argv[1]);getpwd();sprintf(getenv("PWD"), "%s", pwd);return 1;}else if(_argc == 2 && strcmp(_argv[0], "export") == 0){strcpy(myenv, _argv[1]);putenv(myenv);return 1;}else if(_argc == 2 && strcmp(_argv[0], "echo") == 0){if(strcmp(_argv[1], "$?") == 0){printf("%d\n", lastcode);lastcode=0;}else if(*_argv[1] == '$'){char *val = getenv(_argv[1]+1);if(val) printf("%s\n", val);}else{printf("%s\n", _argv[1]);}return 1;}// 特殊处理一下lsif(strcmp(_argv[0], "ls") == 0){_argv[_argc++] = "--color";_argv[_argc] = NULL;}return 0;
}

列举了export建立环境变量、echo打印、cd改变路径等信息        

建立环境变量只需要

 else if(_argc == 2 && strcmp(_argv[0], "export") == 0){
     strcpy(myenv, _argv[1]);
     putenv(myenv);
     return 1;

在bash中putenv即可。

注意:

putenv只是修改了环境变量表的一个指针,让他指向了这个区域。但是这个区域改变之后,就无法获得对应的环境变量。

因此我们需要将区域固定住,额外开辟了一个myenv的空间(cline是变化的)。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com