shell命令解释器.docx

上传人:b****4 文档编号:3487854 上传时间:2022-11-23 格式:DOCX 页数:16 大小:17.50KB
下载 相关 举报
shell命令解释器.docx_第1页
第1页 / 共16页
shell命令解释器.docx_第2页
第2页 / 共16页
shell命令解释器.docx_第3页
第3页 / 共16页
shell命令解释器.docx_第4页
第4页 / 共16页
shell命令解释器.docx_第5页
第5页 / 共16页
点击查看更多>>
下载资源
资源描述

shell命令解释器.docx

《shell命令解释器.docx》由会员分享,可在线阅读,更多相关《shell命令解释器.docx(16页珍藏版)》请在冰豆网上搜索。

shell命令解释器.docx

shell命令解释器

#include

#include

#include

#include

#include

#include

#include

char*stack[1000]={"/"};

intnum=1;

externchar**environ;

/*

内装式shell命令的函数声明:

*/

intlsh_cd(char**args);

intlsh_help(char**args);

intlsh_exit(char**args);

intlsh_pushd(char**args);

intlsh_popd(char**args);

intlsh_dirs(char**args);

intlsh_redirect1(char**args);

intlsh_redirect2(char**args);

intlsh_redirect3(char**args);

intlsh_redirect4(char**args);

intlsh_export(char**args);

intlsh_echo(char**args);

/*

装入的命令列表,紧随其后的是相应的功能。

*/

char*builtin_str[]={

"cd",

"help",

"exit",

"pushd",

"popd",

"dirs",

"export",

"echo"

};

int(*builtin_func[])(char**)={

&lsh_cd,

&lsh_help,

&lsh_exit,

&lsh_pushd,

&lsh_popd,

&lsh_dirs,

&lsh_export,

&lsh_echo

};

intlsh_num_builtins(){

returnsizeof(builtin_str)/sizeof(char*);

}

/*安装在内部的函数实现。

.*/

/**

@briefBultincommand:

changedirectory.

@paramargsListofargs.args[0]is"cd".args[1]isthedirectory.

@returnAlwaysreturns1,tocontinueexecuting.

@briefBultin命令:

改变目录。

@paramargs参数列表。

args[0]是“cd”。

args[1]是目录。

@return总是返回1,继续执行。

*/

intlsh_cd(char**args)

{

if(args[1]==NULL){

fprintf(stderr,"lsh:

expectedargumentto\"cd\"\n");

}else{

if(chdir(args[1])!

=0){

perror("lsh");

}

}

return1;

}

/**

@brief内置命令:

打印的帮助。

@paramargs参数列表。

不检查。

@return总是返回1,继续执行。

*/

intlsh_help(char**args)

{

inti;

printf("Typeprogramnamesandarguments,andhitenter.\n");

printf("Thefollowingarebuiltin:

\n");

for(i=0;i

printf("%s\n",builtin_str[i]);

}

printf("Usethemancommandforinformationonotherprograms.\n");

return1;

}

/**

@brief内置命令:

退出。

@paramargs参数列表。

不检查。

@return总是返回0,终止执行。

*/

intlsh_exit(char**args)

{

return0;

}

//pushd函数:

intlsh_pushd(char**args)

{

if(chdir(args[1])!

=0)

{

perror("lsh");

}

else

{

stack[num++]=get_current_dir_name();

inti=num-1;

while(i>=0)

{

printf("%s",stack[i]);

i--;

}

printf("\n");

}

return1;

}

//popd函数:

intlsh_popd(char**args)

{

if(num<2)

{

printf("popd:

directorystackempty!

\n");

return1;

}

num--;

chdir(stack[num]);

inti=num-1;

while(i>=0)

{

printf("%s",stack[i]);

i--;

}

printf("\n");

return1;

}

//dirs函数:

intlsh_dirs(char**args)

{

if(args[1]==0)

{

inti=num-1;

charm=stack[i];

stack[i]="/";

while(i>=0)

{

printf("%s",stack[i]);

i--;

}

printf("\n");

stack[num-1]=i;

return1;

}

else

{

if(strcmp(args[1],"-c")==0)

{

//memset(stack,0,sizeof(stack));

num=1;

}

if((strcmp(args[1],"-p")==0)&&(strcmp(args[2],"-v")==0))

{

intj=num-1;

while(j>=0)

{

printf("%d%s\n",num-1-j,stack[j]);

j--;

}

}

}

}

intfile1,file2;

//重定向1:

intlsh_redirect1(char**args)

{

file1=open(args[2],O_CREAT|O_RDWR);

file2=dup

(1);

dup2(file1,1);

close(file1);

lsh_launch(args);

dup2(file2,1);

//close(file2);

return1;

}

//重定向2:

intlsh_redirect2(char**args)

{

file1=open(args[2],O_CREAT|O_RDWR);

file2=dup

(2);

dup2(file1,2);

close(file1);

lsh_launch(args);

dup2(file2,2);

close(file2);

return1;

}

//重定向3:

intlsh_redirect3(char**args)

{

file1=open(args[2],O_CREAT|O_RDWR|O_APPEND);

file2=dup

(1);

dup2(file1,1);

close(file1);

lsh_launch(args);

dup2(file2,1);

close(file2);

return1;

}

//重定向4:

intlsh_redirect4(char**args)

{

file1=open(args[2],O_RDONLY|O_TRUNC);

file2=dup(0);

dup2(file1,0);

close(file1);

lsh_launch(args);

dup2(file2,0);

close(file2);

return1;

}

//export:

intlsh_export(char**args)

{

inti=0;

intbuf[100];

int*name;

int*value1;

int*value2;

int*value3;

if(args[1]==NULL)

{

while(environ[i]!

=NULL)

{

printf("%s\n",environ[i]);

i++;

}

}

else

{

strcpy(buf,args[1]);

name=strtok(buf,"=");

strtok(NULL,":

");

value1=getenv(name);

value2=strtok(NULL,":

");

value3=strcat(value1,value2);

setenv(name,value3,1);

}

return1;

}

intlsh_echo(char**args)

{

printf("%s:

%s\n",args[1]+1,getenv(args[1]+1));

return1;

}

/**

@brief启动程序,等待它终止。

@paramargs零终止的参数列表(包括程序)。

@return总是返回1,继续执行。

*/

intlsh_launch(char**args)

{

pid_tpid;

intstatus;

pid=fork();

if(pid==0){

//Childprocess

if(execvp(args[0],args)==-1){

perror("lsh");

}

exit(EXIT_FAILURE);

}elseif(pid<0){

//Errorforking

perror("lsh");

}else{

//Parentprocess

do{

waitpid(pid,&status,WUNTRACED);

}while(!

WIFEXITED(status)&&!

WIFSIGNALED(status));

}

return1;

}

/**

@brief执行shell内置或启动程序。

@paramargs零终止的参数列表。

@return1如果壳牌公司应该继续运行,如果它应该终止

*/

intlsh_execute(char**args)

{

inti;

/*if(args[1]!

=NULL)

if(strcmp(args[2],"|")==0)

{

returnpipe(args);

}*/

if(args[0]==NULL){

//Anemptycommandwasentered.

return1;

}

for(i=0;i

if(strcmp(args[0],builtin_str[i])==0){

return(*builtin_func[i])(args);

}

}

if(args[1]!

=NULL)

if(strcmp(args[1],">")==0)

{

returnlsh_redirect1(args);

}

if(args[1]!

=NULL)

if(strcmp(args[1],"2>")==0)

{

returnlsh_redirect2(args);

}

if(args[1]!

=NULL)

if(strcmp(args[1],">>")==0)

{

returnlsh_redirect3(args);

}

if(strcmp(args[0],"cat")==0)

returnlsh_launch(args);

if(args[1]!

=NULL)

if(strcmp(args[2],"<")==0)

{

returnlsh_redirect4(args);

}

}

#defineLSH_RL_BUFSIZE1024

/**

@brief从stdin读取一行输入。

@return从stdin。

*/

char*lsh_read_line(void)

{

intbufsize=LSH_RL_BUFSIZE;

intposition=0;

char*buffer=malloc(sizeof(char)*bufsize);

intc;

if(!

buffer){

fprintf(stderr,"lsh:

allocationerror\n");

exit(EXIT_FAILURE);

}

while

(1){

//Readacharacter

c=getchar();

//IfwehitEOF,replaceitwithanullcharacterandreturn.

if(c==EOF||c=='\n'){

buffer[position]='\0';

returnbuffer;

}else{

buffer[position]=c;

}

position++;

//Ifwehaveexceededthebuffer,reallocate.

if(position>=bufsize){

bufsize+=LSH_RL_BUFSIZE;

buffer=realloc(buffer,bufsize);

if(!

buffer){

fprintf(stderr,"lsh:

allocationerror\n");

exit(EXIT_FAILURE);

}

}

}

}

#defineLSH_TOK_BUFSIZE64

#defineLSH_TOK_DELIM"\t\r\n\a"

/**

@briefSplitalineintotokens(verynaively).

@paramlineTheline.

@returnNull-terminatedarrayoftokens.

@brief直线分割成令牌(很天真)。

@param线。

@return以null结尾的标记数组)。

@brief从stdin读取一行输入。

@return从stdin。

*/

char**lsh_split_line(char*line)

{

intbufsize=LSH_TOK_BUFSIZE,position=0;

char**tokens=malloc(bufsize*sizeof(char*));

char*token,**tokens_backup;

if(!

tokens){

fprintf(stderr,"lsh:

allocationerror\n");

exit(EXIT_FAILURE);

}

token=strtok(line,LSH_TOK_DELIM);

while(token!

=NULL){

tokens[position]=token;

position++;

if(position>=bufsize){

bufsize+=LSH_TOK_BUFSIZE;

tokens_backup=tokens;

tokens=realloc(tokens,bufsize*sizeof(char*));

if(!

tokens){

free(tokens_backup);

fprintf(stderr,"lsh:

allocationerror\n");

exit(EXIT_FAILURE);

}

}

token=strtok(NULL,LSH_TOK_DELIM);

}

tokens[position]=NULL;

returntokens;

}

/**

@brief循环输入和执行它。

*/

voidlsh_loop(void)

{

char*line;

char**args;

intstatus;

charname[100];

charaddr[100];

do{

gethostname(name,sizeof(name));

printf("<%s>@<%s>:

<%s>$",getlogin(),name,getcwd(addr,sizeof(addr)));

line=lsh_read_line();

args=lsh_split_line(line);

status=lsh_execute(args);

free(line);

free(args);

}while(status);

}

/*

*@brief主要入口点。

*@param命令行参数个数参数计数。

*@paramargv参数向量。

*@return地位codeLoad配置文件,如果任何。

*/

intmain(intargc,char**argv)

{

//加载配置文件,如果有的话。

sigset_tsign;

sigemptyset(&sign);

sigaddset(&sign,SIGQUIT);

sigprocmask(SIG_BLOCK,&sign,NULL);

voidmy_handler(ints)

{

printf("Caughtsignal%d\n",s);

}

structsigactionsi;

si.sa_handler=my_handler;

sigemptyset(&si.sa_mask);

si.sa_flags=0;

sigaction(SIGINT,&si,NULL);

//运行命令循环。

lsh_loop();

//执行任何关闭/清理。

sigprocmask(SIG_UNBLOCK,&sign,NULL);

returnEXIT_SUCCESS;

}

 

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 表格模板 > 合同协议

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1