셸 의 실현
먼저 셸 의 원 리 를 해석 하 는 글 입 니 다. 저 에 게 큰 도움 이 되 지 않 습 니 다. 저 는 아직 완전한 셸 을 만 들 필요 가 없 기 때문에 자료 만 대충 보 았 습 니 다.http://files.linjian.org/articles/bash_study/bash_linjian.html
그 다음 에 다음 두 편의 글 입 니 다. 안의 코드 가 아주 좋 습 니 다. 셸 의 기본 기능 을 실 현 했 고 그의 코드 도 붙 여 보 았 습 니 다. 단점 은 내부 명령 을 실현 하지 못 한 것 입 니 다.
http://www.jiechic.com/archives/24.html
http://www.jiechic.com/archives/25.html
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #define normal 0 /* */
- #define out_redirect 1 /* */
- #define in_redirect 2 /* */
- #define have_pipe 3 /* */
-
- void print_prompt(); /* */
- void get_input(char *); /* */
- void explain_input(char *buf, int *argcount, char arglist[100][256]); /* */
- void do_cmd(int argcount, char arglist[100][256]); /* */
- int find_command(char *); /* */
-
- int main(int argc, char **argv)
- {
- int i;
- int argcount = 0;
- char arglist[100][256];
- //char **arg = NULL;
- char *buf = NULL;
- buf = (char *)malloc(256);
- if( buf == NULL ) {
- perror("malloc failed");
- exit(-1);
- }
- while(1) {
- /* buf */
- memset(buf, 0, 256);
- print_prompt();
- get_input(buf);
- /* exit logout */
- if( strcmp(buf,"exit
") == 0 || strcmp(buf,"logout
") == 0 )
- break;
- for (i=0; i
- {
- arglist[i][0]='\0';
-
- }
- argcount = 0;
- explain_input(buf, &argcount, arglist);
- do_cmd(argcount, arglist);
-
- }
- if(buf != NULL) {
- free(buf);
- buf = NULL;
- }
- exit(0);
- }
-
- void print_prompt()
- {
- printf("myshell$$ ");
- }
-
- /* */
- void get_input(char *buf)
- {
- int len = 0;
- int ch;
- ch = getchar();
- while (len '
') {
- buf[len++] = ch;
- ch = getchar();
- }
- if(len == 256) {
- printf("command is too long
");
- exit(-1); /* */
- }
- buf[len] = '
';
- len++;
- buf[len] = '\0';
-
- }
-
- /* buf , arglist ,
*/
- /* "ls -l /tmp", arglist[0]、arglist[1]、arglsit[2] ls、-l /tmp */
- void explain_input(char *buf, int *argcount, char arglist[100][256])
- {
- char *p = buf;
- char *q = buf;
- int number = 0;
- while (1) {
- if ( p[0] == '
' )
- break;
- if ( p[0] == ' ' )
- p++;
- else {
- q = p;
- number = 0;
- while( (q[0]!=' ') && (q[0]!='
') ) {
- number++;
- q++;
- }
- strncpy(arglist[*argcount], p, number+1);
- arglist[*argcount][number] = '\0';
- *argcount = *argcount + 1;
- p = q;
- }
- }
- }
-
- void do_cmd(int argcount, char arglist[100][256])
- {
- int flag = 0;
- int how = 0; /* >、
- int background = 0; /* & */
- int status;
- int i;
- int fd;
- char* arg[argcount+1];
- char* argnext[argcount+1];
- char* file;
- pid_t pid;
- /* */
- for (i=0; i
- arg[i] = (char *) arglist[i];
- }
- arg[argcount] = NULL;
- /* */
- for (i=0; i
- if (strncmp(arg[i], "&",1) == 0) {
- if (i == argcount-1) {
- background = 1;
- arg[argcount-1] = NULL;
- break;
- }
- else {
- printf("wrong command
");
- return ;
- }
- }
- }
- for (i=0; arg[i]!=NULL; i++) {
- if (strcmp(arg[i], ">") == 0 ) {
- flag++;
- how = out_redirect;
- if (arg[i+1] == NULL)
- flag++;
- }
- if ( strcmp(arg[i],") == 0 ) {
- flag++;
- how = in_redirect;
- if(i == 0)
- flag++;
- }
- if ( strcmp(arg[i],"|")==0 ) {
- flag++;
- how = have_pipe;
- if(arg[i+1] == NULL)
- flag++;
- if(i == 0 )
- flag++;
- }
- }
- /* flag 1, > ,
- , "ls -l /tmp >" */
- if (flag > 1) {
- printf("wrong command
");
- return;
- }
- if (how == out_redirect) { /* > */
- for (i=0; arg[i] != NULL; i++) {
- if (strcmp(arg[i],">")==0) {
- file = arg[i+1];
- arg[i] = NULL;
- }
- }
- }
- if (how == in_redirect) { /*
- for (i=0; arg[i] != NULL; i++) {
- if (strcmp (arg[i],") == 0) {
- file = arg[i+1];
- arg[i] = NULL;
- }
- }
- }
- if (how == have_pipe) { /* | */
- /* argnext , shell */
- for (i=0; arg[i] != NULL; i++) {
- if (strcmp(arg[i],"|")==0) {
- arg[i] = NULL;
- int j;
- for (j=i+1; arg[j] != NULL; j++) {
- argnext[j-i-1] = arg[j];
- }
- argnext[j-i-1] = arg[j];
- break;
- }
- }
- }
- if ( (pid = fork())
- printf("fork error
");
- return;
- }
- switch(how) {
- case 0:
- /* pid 0 , */
- /* >、
- if (pid == 0) {
- if ( !(find_command(arg[0])) ) {
- printf("%s : command not found
", arg[0]);
- exit (0);
- }
- execvp(arg[0], arg);
- exit(0);
- }
- break;
- case 1:
- /* > */
- if (pid == 0) {
- if ( !(find_command(arg[0])) ) {
- printf("%s : command not found
",arg[0]);
- exit(0);
- }
- fd = open(file,O_RDWR|O_CREAT|O_TRUNC,0644);
- dup2(fd,1);
- execvp(arg[0],arg);
- exit(0);
- }
- break;
- case 2:
- /*
- if (pid == 0) {
- if ( !(find_command (arg[0])) ) {
- printf("%s : command not found
",arg[0]);
- exit(0);
- }
- fd = open(file,O_RDONLY);
- dup2(fd,0);
- execvp(arg[0],arg);
- exit(0);
- }
- break;
- case 3:
- /* | */
- if(pid == 0) {
- int pid2;
- int status2;
- int fd2;
- if ( (pid2 = fork())
- printf("fork2 error
");
- return;
- }
- else if (pid2==0) {
- if ( !(find_command(arg[0])) ) {
- printf("%s : command not found
",arg[0]);
- exit(0);
- }
- fd2 = open("/tmp/youdonotknowfile",
- O_WRONLY|O_CREAT|O_TRUNC,0644);
- dup2(fd2, 1);
- execvp(arg[0], arg);
- exit(0);
- }
- if (waitpid(pid2, &status2, 0) == -1)
- printf("wait for child process error
");
- if ( !(find_command(argnext[0])) ) {
- printf("%s : command not found
",argnext[0]);
- exit(0);
- }
- fd2 = open("/tmp/youdonotknowfile",O_RDONLY);
- dup2(fd2,0);
- execvp (argnext[0],argnext);
- if ( remove("/tmp/youdonotknowfile") )
- printf("remove error
");
- exit(0);
- }
- break;
- default:
- break;
- }
- /* &, , */
- if ( background == 1 ) {
- printf("[process id %d]
",pid);
- return ;
- }
- /* */
- if (waitpid (pid, &status,0) == -1)
- printf("wait for child process error
");
- }
-
- /* */
- int find_command (char *command)
- {
- DIR* dp;
- struct dirent* dirp;
- char *path[] = { "./", "/bin", "/usr/bin", NULL};
- /* , "./fork" */
- if( strncmp(command,"./",2) == 0 )
- command = command + 2;
- /* 、/bin /usr/bin */
- int i = 0;
- while (path[i] != NULL) {
- if ( (dp = opendir(path[i]) ) == NULL)
- printf ("can not open /bin
");
- while ( (dirp = readdir(dp)) != NULL) {
- if (strcmp(dirp->d_name,command) == 0) {
- closedir(dp);
- return 1;
- }
- }
- closedir (dp);
- i++;
- }
- return 0;
- }
다음 코드 는 제 가 직접 쓴 것 입 니 다. cd, kill 과 같은 신호 와 일부 내부 명령 을 실 현 했 습 니 다.
- /**********************************************************
- , ,
- :
- ls
- ls &
- ls -l
- ls > in
- cat out
- ls | cat
- cd ..
- cd /
- kill -9 pid
- ***********************************************************/
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #define M 1024
-
- void intHandler()// ctrl-c
- {
- printf("
");
- }
-
- int main()
- {
- int i,j,n;
- int flag_back,flag_in,flag_out,flag_pipe,pid,fd_in,fd_out,status,pid2,status2,fd2;// : , , , ,
- char command[M],path[M],*usr,*com[M],*buf,outfile[M],infile[M],*com2[M];
- while(1)
- {
- signal(SIGINT,intHandler);// ctrl-c
- if((usr=getlogin()) == NULL)//
- {
- exit(0);
- }
- printf("%s:",usr);
-
- if(getcwd(path,sizeof(path)-1) == NULL)//
- {
- exit(0);
- }
- printf("%s",path);
- printf(">");
- memset(command,0,sizeof(command));//
- memset(com,0,sizeof(com));
- memset(com2,0,sizeof(com2));
- flag_back=0;
- flag_in=0;
- flag_out=0;
- flag_pipe=0;
- n=0;
-
- gets(command);//
-
- buf=strtok(command," ");// ,
- while( buf!= NULL )
- {
- com[n]=buf;
- n++;
- buf=strtok(NULL," ");
- }
-
- if (!strcmp(com[0],"cd"))// cd
- {
- if (n != 1)
- {
- chdir(com[1]);
- }
- }
- else if (!strcmp(com[0],"kill"))// kill, kill -9 pid
- {
- kill(atoi(com[2]),atoi(com[1]+1));
- }
- else if (!strcmp(command,"exit")||!strcmp(command,"logout"))//
- {
- break;
- }
- else if (!strcmp(command,""))//
- {
- continue;
- }
- else
- {
- for ( i = 0; i
- {
- if (!strcmp(com[i],"&"))//
- {
- flag_back=1;
- for ( j = i; j
- {
- com[j]=com[j+1];
- }
- com[n-1]=NULL;
- n--;
- i--;
- }
- else if (!strcmp(com[i],">"))//
- {
- flag_out=1;
- strcpy(outfile,com[i+1]);
- for ( j = i; j
- {
- com[j]=com[j+2];
- }
- com[n-2]=NULL;
- n-=2;
- i--;
- }
- else if (!strcmp(com[i],"))//
- {
- flag_in=1;
- strcpy(infile,com[i+1]);
- for ( j = i; j
- {
- com[j]=com[j+2];
- }
- com[n-2]=NULL;
- n-=2;
- i--;
- }
- else if (!strcmp(com[i],"|"))//
- {
- flag_pipe=1;
- for ( j = 0; j
- {
- com2[j]=com[j];
- }
- com2[i]=NULL;
- for ( j = 0; j
- {
- com[j]=com[j+i+1];
- }
- com[n-i-1]=NULL;
- break;
- }
- }
- if ( (pid = fork()) //
- {
- printf("fork error
");
- return;
- }
- if (!pid)
- {
- if (flag_out)
- {
- fd_out = open(outfile,O_RDWR|O_CREAT|O_TRUNC,0644);//
- dup2(fd_out,1);
- }
- if (flag_in)
- {
- fd_in = open(infile,O_RDONLY);//
- dup2(fd_in,0);
- }
- if (flag_pipe)
- {
- if ( (pid2 = fork()) //
- {
- printf("fork2 error
");
- return;
- }
- else if (!pid2)
- {
- fd2 = open("/tmp/wb",O_WRONLY|O_CREAT|O_TRUNC,0644);//
- dup2(fd2,1);
- execvp(com2[0],com2);
- exit(0);
- }
- if (waitpid(pid2, &status2, 0) == -1)
- {
- //printf("wait for child process error
");
- }
- fd2 = open("/tmp/wb",O_RDONLY);
- dup2(fd2,0);
- }
- execvp(com[0],com);//
- remove("/tmp/wb");
- exit(0);
- }
- else
- {
- if (flag_back)
- {
- printf("[process id %d]
",pid);// ,
- continue;
- }
- else
- {
- if (waitpid (pid,&status,0) == -1)
- {
- //printf("wait for child process error
");
- }
- }
- }
- }
- }
- return 0;
- }
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
양식 제출 후 제출 버튼 비활성화텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.