bash命令解释器
内核<----->命令解释器(shell,bash,sh,tcsh)<----->用户
两者之间通过命令解释器进行交互
linux中输入的执行命令来源都是bash
bash->bash(fork()产生的子进程) 再通过exec()替换这个进程,变成用户需要执行的进程
依据这个创建mybash
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<assert.h>
#include<sys/wait.h>
#include<pwd.h>
void info()
{
char *s = "$";
int uid = getuid();//获取用户id
if(uid == 0)//id为0的则是管理员root
{
s = "#";
}
struct passwd *pd = getpwuid(uid);//从id获取到用户信息
if(pd == NULL)//如果用户信息是空的则说明失败
{
printf("mybash $");
fflush(stdout);
return;
}
char host[128] = {0};
if(gethostname(host,128) == -1)//获取主机名
{
printf("myabsh $");
fflush(stdout);
return;
}
char path[128] = {0};
getcwd(path,128);//获取当前路径
printf("%s@%s:/%s%s",pd->pw_name,host,path,s);
ffush(stdout);
}
int main()
{
while(1)
{
char buff[128] = {0};
info();
fgets(buff,128,stdin);//从键盘获取字符串存入buff中
buff[strlen(buff) - 1] == '\0';//给输入的字符串后面加上结束符
char *s = strtok(buff," ");//根据空格分开输入的字符
char *tmp = s; //存放第一个用空格分开的字符
if(strcmp(tmp,"exit") == 0)//如果这个字符是exit就退出
{
break;
}
char *myargv[10] = {0};
int i = 0;
while(s!=NULL)//利用循环将输入的字符分开,存放在myargv中
{
myargv[i++] = s;
s = strtok(NULL," ");
}
if(strcmp(tmp,"cd") == 0)//对比第一个字符是否为cd切换路径
{
if(myargv[1]!=NULL)//如果是cd,并且后面输入了路径则继续
{
if(chdir(myargv[1]) == -1)//切换路径失败则打印失败,继续循环程序
{
perror("cd :error");
}
}
continue;
}
//需要用到进程的,则复制出新的进程,将新进程替换为要执行的进程
pid_t pid = fork();//复制操作
assert(pid!=-1);
if(pid == 0)//如果是子进程则进入
{
if(execvp(tmp,myargv)==-1)//替换操作
{
perror("exec error");
exit(0);
}
}
wait(NULL);//等待子进程结束,避免僵死进程
}
}
能实现以下操作: