【Linux】手把手教你做一个简易shell(命令行解释器)
2024-01-02 20:47:05
> 作者简介:?旧言~,目前大二,现在学习Java,c,c++,Python等
> 座右铭:松树千年终是朽,槿花一日自为荣。> 目标:自己能写出一个简易shell(命令行解释器)
> 毒鸡汤:要让人觉得毫不费力,只能背后极其努力。
> 望小伙伴们点赞👍收藏?加关注哟💕💕?
原理:
????????shell是命令行解释器,当有命令需要执行时,shell创建子进程,让子进程执行命令,而shell只需等待子进程退出即可。
实现思路:
- 获取命令行(fgets函数)。
- 解析命令行(strtok分割字符串)。
- 创建子进程(fork函数)。
- 替换子进程(exec函数族)。
- 等待子进程退出(waitpid函数)。
代码如下:
#include <stdio.h>
#include <pwd.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
#define LEN 1024 //命令最大长度
#define NUM 32 //命令拆分后的最大个数
int main()
{
char cmd[LEN]; //存储命令
char* myargv[NUM]; //存储命令拆分后的结果
char hostname[32]; //主机名
char pwd[128]; //当前目录
while (1){
//获取命令提示信息
struct passwd* pass = getpwuid(getuid());
gethostname(hostname, sizeof(hostname)-1);
getcwd(pwd, sizeof(pwd)-1);
int len = strlen(pwd);
char* p = pwd + len - 1;
while (*p != '/'){
p--;
}
p++;
//打印命令提示信息
printf("[%s@%s %s]$ ", pass->pw_name, hostname, p);
//读取命令
fgets(cmd, LEN, stdin);
cmd[strlen(cmd) - 1] = '\0';
//拆分命令
myargv[0] = strtok(cmd, " ");
int i = 1;
while (myargv[i] = strtok(NULL, " ")){
i++;
}
pid_t id = fork(); //创建子进程执行命令
if (id == 0){
//child
execvp(myargv[0], myargv); //child进行程序替换
exit(1); //替换失败的退出码设置为1
}
//shell
int status = 0;
pid_t ret = waitpid(id, &status, 0); //shell等待child退出
if (ret > 0){
printf("exit code:%d\n", WEXITSTATUS(status)); //打印child的退出码
}
}
return 0;
}
运行结果:
说明:
当执行./myshell命令后,便是我们自己实现的shell在进行命令行解释,我们自己实现的shell在子进程退出后都打印了子进程的退出码,我们可以根据这一点来区分我们当前使用的是Linux操作系统的shell还是我们自己实现的shell。
🌟结束语
? ? ? ?今天内容就到这里啦,时间过得很快,大家沉下心来好好学习,会有一定的收获的,大家多多坚持,嘻嘻,成功路上注定孤独,因为坚持的人不多。那请大家举起自己的小手给博主一键三连,有你们的支持是我最大的动力💞💞💞,回见。
文章来源:https://blog.csdn.net/AAlykk/article/details/135299029
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!