(一)bash流程框架图:
(二)代码实现
#ifndef MYBASH_H
#define MYBASH_H
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <signal.h>
#include <pwd.h>
#include <sys/utsname.h>
typedef enum returncode
{
ADDR_NULL = 0,
EXIT,
MYCD,
EXEC
}returncode;
void OutPutInfo();
char* GetCmd();
returncode CmdResolve(char* cmd, char* cmdbuff[]);
void ChildExec(char* cmdbuff[], const char* cmd);
void Zombie();
int IsBack(const char* cmdbuff);
void Mycd(const char* path);
#endif
#include "mybash.h"
void OutPutInfo()
{
char flg = '$';
struct passwd* pw = getpwuid(getuid());
if(pw == NULL)
{
return;
}
if(pw->pw_uid == 0)
{
flg = '#';
}
struct utsname buff;
uname(&buff);
char pathname[128] = {
0};
getcwd(pathname, 127);
int len_homepath = strlen(pw->pw_dir);
char* p = pathname + len_homepath;
if(strncmp(pathname, pw->pw_dir, len_homepath) == 0)
{
memset(pathname, 0, len_homepath);
strcat(pathname, "~");
strcat(pathname, p);
}
printf("%s@%s:%s%c ",pw->pw_name,buff.nodename, pathname,flg);
fflush(stdout);
}
char* GetCmd()
{
char* cmd = (char*)malloc(sizeof(char) * 128);
memset(cmd, 0, sizeof(char) * 128);
fgets(cmd, 127, stdin);
cmd[strlen(cmd) - 1] = '\0';
return cmd;
}
returncode CmdResolve(char* cmd, char* cmdbuff[])
{
if(cmd == NULL || cmdbuff == NULL)
{
return ADDR_NULL;
}
char *s = strtok(cmd, " ");
int i = 0;
while (s != NULL)
{
cmdbuff[i++] = s;
s = strtok(NULL, " ");
}
cmdbuff[i] = NULL;
if(strcmp(cmdbuff[0], "exit") == 0)
{
return EXIT;
}
if(strcmp(cmdbuff[0], "cd") == 0)
{
return MYCD;
}
else
{
return EXEC;
}
}
void ChildExec(char* cmdbuff[], const char* cmd)
{
if(cmdbuff == NULL || cmd == NULL)
return;
char pathname[128] = {
"/home/jiege/mybash/bin/"};
strcat(pathname, cmdbuff[0]);
int ret = IsBack(cmd);
pid_t pid = fork();
if(pid == -1)
{
perror("fork err");
return;
}
if(pid == 0)
{
execv(pathname, cmdbuff);
perror("command not found");
exit(0);
}
else
{
if(ret == 0)
{
wait(NULL);
}
}
}
void Zombie()
{
wait(NULL);
}
int IsBack(const char* cmd)
{
if(cmd == NULL)
return -1;
if(strstr(cmd, "&") != NULL)
return 1;
return 0;
}
void Mycd(const char* path)
{
if(path == NULL)
return;
if(chdir(path) == -1)
{
perror("cd err");
}
}
#include "mybash.h"
int main()
{
signal(SIGCHLD, Zombie);
char* cmd = NULL;
while(1)
{
OutPutInfo();
cmd = GetCmd();
char* cmdbuff[32] = {
0};
returncode ret = CmdResolve(cmd, cmdbuff);
if(ret == EXIT)
{
free(cmd);
cmd = NULL;
break;
}
else if(ret == MYCD)
{
Mycd(cmdbuff[1]);
free(cmd);
cmd = NULL;
}
else if(ret == ADDR_NULL)
{
free(cmd);
cmd = NULL;
continue;
}
else
{
ChildExec(cmdbuff, cmd);
}
}
return 0;
}
objects=main.o mybash.o
mybash:$(objects)
gcc -o mybash $(objects)
$(objects): mybash.h main.c mybash.c
.PHONY:clean
clean:
rm -f mybash $(objects)
(三)最终项目文件结构
已上传githubhttps://github.com/HuTaoHub/mybash.git