自制shell MINI型的方法介绍
像普通C程序一样编译运行即可。mini.h
/*filename:mini.h*/
#defineWHITESPACE".,&"
#defineMAX_ARG_LEN10
#defineMAX_DIRS20
#defineMAX_PATH_LEN100
#defineSTD_INPUT0
#defineSTD_OUTPUT1
#defineMAX_ARGS5
structcommand_t{
intargc;
char*name;
char*argv[MAX_ARGS];
};
#defineWHITESPACE".,&"
#defineMAX_ARG_LEN10
#defineMAX_DIRS20
#defineMAX_PATH_LEN100
#defineSTD_INPUT0
#defineSTD_OUTPUT1
#defineMAX_ARGS5
structcommand_t{
intargc;
char*name;
char*argv[MAX_ARGS];
};
mini.c
/************************************************************
*MiniShell
*filename:mini.c
*it'sasimpleshellwrittenbyManio(maniosterATgmail.com)
*Bugs:1.thecommandsmustbesepratedbyonlyonewhitespace
*andmoreandmorebugshere...
*thepartofpipehavn'tbewritten.
*date,addr:08/16/2006Yangshuo,China
************************************************************/
#include<fcntl.h>
#include<stdio.h>
#include<sys/types.h>
#include<sys/wait.h>
#include<string.h>
#include<unistd.h>
#include"mini.h"
//#defineDEBUG1
voidprintLineHead();
voidparseCommand(char*,char**);
char*GetChkFullPath(char**,char**);
main(){
inti,j;/*forcommonuse*/
intstat;/*usedbywait()*/
intisInRedir,isOutRedir,isPipe;
intfid;/*forfileopening*/
charorginalCmd[100];/*storethecommandusertyped*/
char*dir[MAX_DIRS];
structcommand_tcommand;
char*tempstr[7];
/*initialargv
*maybeaerrorwillbeoccuredifargvisnotbeinitialed
*/
for(i=0;i<MAX_ARGS;i++)
command.argv[i]=(char*)malloc(MAX_ARG_LEN);
while(1){
printLineHead();
gets(orginalCmd);/*readuser'sinput*/
#ifdefDEBUG
printf("::::aftergets(orginalCmd):::: ");
printf("orginalCmd=%s ",orginalCmd);
printf(":::::::::::::::::::::::::::::: ");
#endif
/*if"exit"inputed,exittheshell*/
if(strcmp(orginalCmd,"exit")==0)
break;
/*devidecommandlinetoseveralparts*/
parseCommand(orginalCmd,command.argv);
/*gettheamountofargv*/
for(i=0;command.argv[i]!=NULL;i++);
command.argc=i;
#ifdefDEBUG
printf("command.argc=%d ",command.argc);
#endif
#ifdefDEBUG
printf("::::parseCommandcommand.argv:::: ");
printf("command.name=%s ",command.name);
intcommandi;
for(commandi=0;command.argv[commandi]!=NULL;commandi++)
printf("command.argv[%d]=%s ",commandi,command.argv[commandi]);
printf("::::ENDcommand.argv:::: ");
#endif
/*getthedirsfromPATH;PATHisaenviromentvar*/
#ifdefDEBUG
printf("getDirstart=========================== ");
#endif
getDir(dir);
#ifdefDEBUG
intdiri=0;
for(;dir[diri]!=NULL;diri++)
{
printf("inmaindir[%d]is%s ",diri,dir[diri]);
}
#endif
/*getthenameofcommand,thismustgetthefullpathofthefile,buthereisfordebug*/
command.name=GetChkFullPath(command.argv,dir);
#ifdefDEBUG
printf("inmainafterGetChkFullPathcommand.name=%s ",command.name);
#endif
if(command.name==NULL){
/*thecommandinputedisnotvalidorisempty*/
continue;
fprintf(stderr,"Command%snotfound ",command.argv[0]);
}
/*scan<>|,isPipeisInRedirandisOutRedirstorethepositionof"<>|"*/
isPipe=isInRedir=isOutRedir=0;
for(i=0;command.argv[i]!=NULL;i++)
{
if(strcmp(command.argv[i],"<")==0){
isInRedir=i;
}
if(strcmp(command.argv[i],">")==0){
isOutRedir=i;
}
if(strcmp(command.argv[i],"|")==0){
isPipe=i;
}
}
#ifdefDEBUG
printf("isin,inout,ispipe:%d%d%d ",isInRedir,isOutRedir,isPipe);
#endif
#ifdefDEBUG
command.argv[3]=NULL;
printf("showtheargvswhichisnotset ");
for(i=0;i<MAX_ARGS;i++)
printf("argv[%d]=%s ",i,command.argv[i]);
#endif
/*excuteacommmand*/
if(fork()==0){
#ifdefDEBUG
printf("::::::::::::::::Infork==0:::::::::::::::::: ");
#endif
if(isInRedir){
fid=open(command.argv[isInRedir+1],O_RDONLY);
close(STD_INPUT);//closestandardinput
dup(fid);//redirectfidtostandardinput
close(fid);
command.argv[isInRedir]=NULL;/*ignorethewordafterisInRedir*/
#ifdefDEBUG
printf("::::parseCommandcommand.argv:::: ");
printf("command.name=%s ",command.name);
for(commandi=0;command.argv[commandi]!=NULL;commandi++)
printf("command.argv[%d]=%s ",commandi,command.argv[commandi]);
printf("::::ENDcommand.argv:::: ");
#endif
}
if(isOutRedir){
fid=open(command.argv[isOutRedir+1],O_WRONLY|O_CREAT);
close(STD_OUTPUT);
dup(fid);
close(fid);
command.argv[isOutRedir]=NULL;
#ifdefDEBUG
printf("::::parseCommandcommand.argv:::: ");
printf("command.name=%s ",command.name);
for(commandi=0;command.argv[commandi]!=NULL;commandi++)
printf("command.argv[%d]=%s ",commandi,command.argv[commandi]);
printf("::::ENDcommand.argv:::: ");
#endif
}
execv(command.name,command.argv);/*excutethecommand*/
#ifdefDEBUG
printf("::::::::::::::::Infork==0END:::::::::::::::::: ");
#endif
}else{
#ifdefDEBUG
printf("::::::::::::::::Infork!=0:::::::::::::::::: ");
#endif
wait(&stat);/*waitfortheendofchildprocess*/
#ifdefDEBUG
printf("::::::::childprocessdone!::INFORK!=0:END::::: ");
#endif
}
//loopcount=0;
}/*while*/
#ifdefDEBUG
printf("Shellterminaled ");
#endif
}
voidprintLineHead()
{
printf("MANIO'sminiSHELL>");
}
/**************************************************************
parseCommand()
*sepratecLinebyWHITESPACE,putthemtopchar[]
*#defineWHITESPACE".,&"
*bugs:ThiscodedoesnothandlemultipleWHITESPACEcharacters
***************************************************************
*/
voidparseCommand(char*cLine,char*pchar[]){
intargc;
char*tCLine;
char**clPtr;
//Initialization
tCLine=cLine;
clPtr=&tCLine;
argc=0;
//ThiscodedoesnothandlemultipleWHITESPACEcharacters
while((pchar[argc++]=strsep(clPtr,WHITESPACE))!=NULL);
pchar[argc--]=NULL;//Nullterminatedlistofstrings
}
/****************************************************************
*getthepathinPATHsepratedby":"
*****************************************************************
*/
intgetDir(char*dir[])
{
inti;
char*s;
char*oldpath;
char*ppath;
s=(char*)getenv("PATH");
#ifdefDEBUG
printf("sis%s ",s);
printf("s2=====%c ",s[2]);
#endif
oldpath=(char*)malloc(strlen(s)+1);
strcpy(oldpath,s);
#ifdefDEBUG
printf("oldpathis%s ",oldpath);
#endif
ppath=oldpath;
#ifdefDEBUG
printf("ppathcharis%c ",*ppath);
#endif
for(i=0;*ppath!='';ppath++)
{
#ifdefDEBUG
printf("inforppathcharis%c ",*ppath);
#endif
if(*ppath==':')
{
dir[i++]=oldpath;
*ppath='';
oldpath=ppath+1;
}
}
dir[i]=NULL;
#ifdefDEBUG
intdiri=0;
for(;dir[diri]!=NULL;diri++)
{
printf("dir[%d]is%s ",diri,dir[diri]);
}
#endif
return1;
}
/****************************************************************
*getandcheckthefullpathwhichtheuserinputed
*dir:dirsinPATH
*argv:argvincommand_t
*****************************************************************
*/
char*GetChkFullPath(char**argv,char**dir)
{
#ifdefDEBUG
printf(":::::::::::GetChkFullPathstart ");
printf("argv[0]=%s dir[0]=%s ",argv[0],dir[0]);
#endif
charfullpath[MAX_PATH_LEN];
char*result;
inti;
result=NULL;
if(*argv[0]!='/')
{
//*argv[0]!=''
#ifdefDEBUG
printf("JUGEargv[0]!=/ ");
#endif
for(i=0;dir[i]!=NULL;i++)
{
strcpy(fullpath,dir[i]);
strcat(fullpath,"/");
strcat(fullpath,argv[0]);
#ifdefDEBUG
printf("afterstrcatfullpath:%s ",fullpath);
#endif
if(access(fullpath,X_OK|F_OK)!=-1){
#ifdefDEBUG
printf("FOUND%sin%s ",argv[0],dir[i]);
#endif
result=(char*)malloc(strlen(fullpath)+1);
strcpy(result,fullpath);
break;
}
}
}else{
#ifdefDEBUG
printf("JUGEargv[0]==/ ");
#endif
if(access(argv[0],X_OK|F_OK)!=-1){
#ifdefDEBUG
printf("FOUND%s ",argv[0]);
#endif
result=(char*)malloc(strlen(argv[0])+1);
strcpy(result,argv[0]);
}
}
if(result==NULL){
printf("%sisnotacommand. ",argv[0]);
returnNULL;
}else{
#ifdefDEBUG
printf("GetChkFullPathendresult==%s ",result);
#endif
returnresult;
}
}
*MiniShell
*filename:mini.c
*it'sasimpleshellwrittenbyManio(maniosterATgmail.com)
*Bugs:1.thecommandsmustbesepratedbyonlyonewhitespace
*andmoreandmorebugshere...
*thepartofpipehavn'tbewritten.
*date,addr:08/16/2006Yangshuo,China
************************************************************/
#include<fcntl.h>
#include<stdio.h>
#include<sys/types.h>
#include<sys/wait.h>
#include<string.h>
#include<unistd.h>
#include"mini.h"
//#defineDEBUG1
voidprintLineHead();
voidparseCommand(char*,char**);
char*GetChkFullPath(char**,char**);
main(){
inti,j;/*forcommonuse*/
intstat;/*usedbywait()*/
intisInRedir,isOutRedir,isPipe;
intfid;/*forfileopening*/
charorginalCmd[100];/*storethecommandusertyped*/
char*dir[MAX_DIRS];
structcommand_tcommand;
char*tempstr[7];
/*initialargv
*maybeaerrorwillbeoccuredifargvisnotbeinitialed
*/
for(i=0;i<MAX_ARGS;i++)
command.argv[i]=(char*)malloc(MAX_ARG_LEN);
while(1){
printLineHead();
gets(orginalCmd);/*readuser'sinput*/
#ifdefDEBUG
printf("::::aftergets(orginalCmd):::: ");
printf("orginalCmd=%s ",orginalCmd);
printf(":::::::::::::::::::::::::::::: ");
#endif
/*if"exit"inputed,exittheshell*/
if(strcmp(orginalCmd,"exit")==0)
break;
/*devidecommandlinetoseveralparts*/
parseCommand(orginalCmd,command.argv);
/*gettheamountofargv*/
for(i=0;command.argv[i]!=NULL;i++);
command.argc=i;
#ifdefDEBUG
printf("command.argc=%d ",command.argc);
#endif
#ifdefDEBUG
printf("::::parseCommandcommand.argv:::: ");
printf("command.name=%s ",command.name);
intcommandi;
for(commandi=0;command.argv[commandi]!=NULL;commandi++)
printf("command.argv[%d]=%s ",commandi,command.argv[commandi]);
printf("::::ENDcommand.argv:::: ");
#endif
/*getthedirsfromPATH;PATHisaenviromentvar*/
#ifdefDEBUG
printf("getDirstart=========================== ");
#endif
getDir(dir);
#ifdefDEBUG
intdiri=0;
for(;dir[diri]!=NULL;diri++)
{
printf("inmaindir[%d]is%s ",diri,dir[diri]);
}
#endif
/*getthenameofcommand,thismustgetthefullpathofthefile,buthereisfordebug*/
command.name=GetChkFullPath(command.argv,dir);
#ifdefDEBUG
printf("inmainafterGetChkFullPathcommand.name=%s ",command.name);
#endif
if(command.name==NULL){
/*thecommandinputedisnotvalidorisempty*/
continue;
fprintf(stderr,"Command%snotfound ",command.argv[0]);
}
/*scan<>|,isPipeisInRedirandisOutRedirstorethepositionof"<>|"*/
isPipe=isInRedir=isOutRedir=0;
for(i=0;command.argv[i]!=NULL;i++)
{
if(strcmp(command.argv[i],"<")==0){
isInRedir=i;
}
if(strcmp(command.argv[i],">")==0){
isOutRedir=i;
}
if(strcmp(command.argv[i],"|")==0){
isPipe=i;
}
}
#ifdefDEBUG
printf("isin,inout,ispipe:%d%d%d ",isInRedir,isOutRedir,isPipe);
#endif
#ifdefDEBUG
command.argv[3]=NULL;
printf("showtheargvswhichisnotset ");
for(i=0;i<MAX_ARGS;i++)
printf("argv[%d]=%s ",i,command.argv[i]);
#endif
/*excuteacommmand*/
if(fork()==0){
#ifdefDEBUG
printf("::::::::::::::::Infork==0:::::::::::::::::: ");
#endif
if(isInRedir){
fid=open(command.argv[isInRedir+1],O_RDONLY);
close(STD_INPUT);//closestandardinput
dup(fid);//redirectfidtostandardinput
close(fid);
command.argv[isInRedir]=NULL;/*ignorethewordafterisInRedir*/
#ifdefDEBUG
printf("::::parseCommandcommand.argv:::: ");
printf("command.name=%s ",command.name);
for(commandi=0;command.argv[commandi]!=NULL;commandi++)
printf("command.argv[%d]=%s ",commandi,command.argv[commandi]);
printf("::::ENDcommand.argv:::: ");
#endif
}
if(isOutRedir){
fid=open(command.argv[isOutRedir+1],O_WRONLY|O_CREAT);
close(STD_OUTPUT);
dup(fid);
close(fid);
command.argv[isOutRedir]=NULL;
#ifdefDEBUG
printf("::::parseCommandcommand.argv:::: ");
printf("command.name=%s ",command.name);
for(commandi=0;command.argv[commandi]!=NULL;commandi++)
printf("command.argv[%d]=%s ",commandi,command.argv[commandi]);
printf("::::ENDcommand.argv:::: ");
#endif
}
execv(command.name,command.argv);/*excutethecommand*/
#ifdefDEBUG
printf("::::::::::::::::Infork==0END:::::::::::::::::: ");
#endif
}else{
#ifdefDEBUG
printf("::::::::::::::::Infork!=0:::::::::::::::::: ");
#endif
wait(&stat);/*waitfortheendofchildprocess*/
#ifdefDEBUG
printf("::::::::childprocessdone!::INFORK!=0:END::::: ");
#endif
}
//loopcount=0;
}/*while*/
#ifdefDEBUG
printf("Shellterminaled ");
#endif
}
voidprintLineHead()
{
printf("MANIO'sminiSHELL>");
}
/**************************************************************
parseCommand()
*sepratecLinebyWHITESPACE,putthemtopchar[]
*#defineWHITESPACE".,&"
*bugs:ThiscodedoesnothandlemultipleWHITESPACEcharacters
***************************************************************
*/
voidparseCommand(char*cLine,char*pchar[]){
intargc;
char*tCLine;
char**clPtr;
//Initialization
tCLine=cLine;
clPtr=&tCLine;
argc=0;
//ThiscodedoesnothandlemultipleWHITESPACEcharacters
while((pchar[argc++]=strsep(clPtr,WHITESPACE))!=NULL);
pchar[argc--]=NULL;//Nullterminatedlistofstrings
}
/****************************************************************
*getthepathinPATHsepratedby":"
*****************************************************************
*/
intgetDir(char*dir[])
{
inti;
char*s;
char*oldpath;
char*ppath;
s=(char*)getenv("PATH");
#ifdefDEBUG
printf("sis%s ",s);
printf("s2=====%c ",s[2]);
#endif
oldpath=(char*)malloc(strlen(s)+1);
strcpy(oldpath,s);
#ifdefDEBUG
printf("oldpathis%s ",oldpath);
#endif
ppath=oldpath;
#ifdefDEBUG
printf("ppathcharis%c ",*ppath);
#endif
for(i=0;*ppath!='';ppath++)
{
#ifdefDEBUG
printf("inforppathcharis%c ",*ppath);
#endif
if(*ppath==':')
{
dir[i++]=oldpath;
*ppath='';
oldpath=ppath+1;
}
}
dir[i]=NULL;
#ifdefDEBUG
intdiri=0;
for(;dir[diri]!=NULL;diri++)
{
printf("dir[%d]is%s ",diri,dir[diri]);
}
#endif
return1;
}
/****************************************************************
*getandcheckthefullpathwhichtheuserinputed
*dir:dirsinPATH
*argv:argvincommand_t
*****************************************************************
*/
char*GetChkFullPath(char**argv,char**dir)
{
#ifdefDEBUG
printf(":::::::::::GetChkFullPathstart ");
printf("argv[0]=%s dir[0]=%s ",argv[0],dir[0]);
#endif
charfullpath[MAX_PATH_LEN];
char*result;
inti;
result=NULL;
if(*argv[0]!='/')
{
//*argv[0]!=''
#ifdefDEBUG
printf("JUGEargv[0]!=/ ");
#endif
for(i=0;dir[i]!=NULL;i++)
{
strcpy(fullpath,dir[i]);
strcat(fullpath,"/");
strcat(fullpath,argv[0]);
#ifdefDEBUG
printf("afterstrcatfullpath:%s ",fullpath);
#endif
if(access(fullpath,X_OK|F_OK)!=-1){
#ifdefDEBUG
printf("FOUND%sin%s ",argv[0],dir[i]);
#endif
result=(char*)malloc(strlen(fullpath)+1);
strcpy(result,fullpath);
break;
}
}
}else{
#ifdefDEBUG
printf("JUGEargv[0]==/ ");
#endif
if(access(argv[0],X_OK|F_OK)!=-1){
#ifdefDEBUG
printf("FOUND%s ",argv[0]);
#endif
result=(char*)malloc(strlen(argv[0])+1);
strcpy(result,argv[0]);
}
}
if(result==NULL){
printf("%sisnotacommand. ",argv[0]);
returnNULL;
}else{
#ifdefDEBUG
printf("GetChkFullPathendresult==%s ",result);
#endif
returnresult;
}
}
本文地址:http://www.45fan.com/a/luyou/72671.html