linux编程命令解释器 linux常见的命令解析器

【Linux】实现一个简单的shell命令解释器姓名:罗学元学号:21181214375学院:广州研究院
【嵌牛导读】shell命令解释器该包含哪些部分
【嵌牛鼻子】shell命令解释器该包含哪些部分
【嵌牛提问】shell命令解释器该包含哪些部分
我们所做的这个简单的shell命令解释器可以实现简单的常用的基本命令,如ls、pwd、cd、cd - 、cd ~ 等
根据简单命令的定义 , 它的第一个参数是要执行的命令,后面的参数作为该命令的参数 。
要执行的命令有两种情况:
一种是外部命令: 也就是对应着磁盘上的某个程序,例如 pwd、ls等等 。对于这种外部命令,我们首先要到指定的路径下找到它 , 然后再执行它 。
另一种是内部命令:内部命令并不对应磁盘上的程序,例如cd等等,它需要shell自己来决定该如何执行 。例如对 cd 命令,shell就应该根据它后面的参数改变当前路径 。
【linux编程命令解释器 linux常见的命令解析器】 对于外部命令,需要创建一个子进程来执行它,本质就是fork+exec
#include stdio.h
#include stdlib.h
#include assert.h
#include string.h
#include pwd.h
#include sys/utsname.h
#include sys/types.h
#include unistd.h
#define MAX 10
#define STRLEN 128
#define PATH "/bin/" //系统bin路径位置
char OLDPWD[STRLEN]={0}; //记录上一次的命令,为了cd -这条命令
//================================================================================
//每次敲回车输出当前所在用户信息
//普通用户和root用户的提示符区别
void Printf_Info()
{
char flag='$';
struct passwd *pw=getpwuid(getuid());
assert(pw!=NULL);
//uid为0则为root用户
if(pw-pw_uid==0)
{
flag='#';
}
struct utsname hostname; //主机名
uname(hostname);
char node[STRLEN]={0};
strcpy(node,hostname.nodename); //获取网络上的名称
char* name=strtok(node,".");
//获取绝对路径
char path[STRLEN]={0};
getcwd(path,STRLEN-1);
char*p=path+strlen(path); //p指向绝对路径的末尾
while(*p!='/')
{
p--;
}
//p指向路径末尾往前的第一个‘/’位置处
if(strlen(path)!=1)
{
p++; //++前,p-'/'
}
if(strcmp(path,pw-pw_dir)==0)
{
p="~";
}
printf("\033[;32mMyBash[%s@%s %s]%c\033[0m",pw-pw_name,name,p,flag);
//\033[47;31mThis is a color test\033[0m设置打印结果的颜色
fflush(stdout);
}
//================================================================================
void Mycd(char*path)
{
//第一个字符串为cd而第二为空 如:cd 则结束本轮循环
if(path==NULL)
{
exit(0);
}
//cd ~ 回到用户根目录
if(strcmp(path,"~")==0)
{
struct passwd*pw=getpwuid(getuid());
path=pw-pw_dir;
}
//cd - 回到上一次的位置
if(strcmp(path,"-")==0)
{
//若是第一次输入命令,则cd -命令不存在!
if(strlen(OLDPWD)==0)
{
printf("\033[;31mMyBash:cd:OLDPWD not set\n\033[0m");
return ;
}
//否则把上一次的命令给path
path=OLDPWD;
}
//getpwd记录当前工作目录的绝对路径
char oldpwd[STRLEN]={0};
getcwd(oldpwd,STRLEN-1);
if(-1==chdir(path))//反之则不是空,则通过chdir系统调用进入到该目录中
{
char err[128]="\033[;31mMybash: cd \033[0m";
strcat(err,path);
perror(err);
}
//每次执行完cd命令后,把工作路径赋给OLDPWD
strcpy(OLDPWD,oldpwd);
}
//================================================================================

推荐阅读