Write a mock shell under Linux

Source: Internet
Author: User
Tags strcmp

1, first understand the Shell's basic framework

650) this.width=650; "src=" Http://s4.51cto.com/wyfs02/M00/83/46/wKioL1duhrXze92MAAAmKDBM0i0805.png "title=" 2016-06-25 21-26-40 screen. png "alt=" Wkiol1duhrxze92maaamkdbm0i0805.png "/>

As shown

[User name @ Host name current path]$ command

Execute command result

Goal: Complete a simple shell (input command to get execution results)

So the framework is divided into:

1, "Prompt" $ display-----a bunch of function calls can be

2, the execution of the command-----read into the data, to parse, get argv[], the implementation of EXECVP

3. Separate processing for built-in command CD

#include  <stdio.h> #include  <pwd.h> #include  <sys/types.h> #include  < unistd.h> #include  <string.h> #include  <stdlib.h>void prompt () {  struct  passwd * p1;  char username[64];  char hostname[256];   char pathname[1024];  //Get user name   p1=getpwuid (getuid ());   //Get path   &NBSP;GETCWD (pathname,sizeof (pathname));   //gets the hostname---returns 0 correct   if (gethostname (hostname,sizeof ( hostname) ==0)   {    printf ("[diy %[email protected]%s:%s ]", p1- >pw_name,hostname,pathname);   }  else  {    printf ("[DIY  %[email protected]:%s ] ", p1->pw_name,pathname);   }  if (Geteuid () ==0)   {    printf ("#");  }  else  {    &NBSP;PRINTF ("$"); &NBSP;&NBSP;}} Int main () {  while (1)   {    prompt ();     Fflush (stdout);     //Get environment Variables     char buf[1024];     memset (buf,0,sizeof (BUF))     size_t size=read (0,buf,sizeof (BUF)-1);         if (size>0)     {       buf[size-1]= ' + ';     }   // printf ("%s\n", buf);     char *p=buf;    int i=0;    char * my_ Argv[64]={0};    my_argv[0]=p;    while (*p!=0)      {      if (*p== '   ')       {         *p= ';        ++p;         my_argv[++i]=p;      }      else       {        ++p;       }    }    pid_t id=fork ();         if (id==0)  //sub-process     {             if (strcmp (my_argv[0], "CD") ==0)       {         chdir (my_argv[1]);      }       else      {         EXECVP (MY_ARGV[0],MY_ARGV);      }    }     else  //Parent Process     {      pid_t ret=waitpid (id,null,0);      }  }  return 0;} 

650) this.width=650; "src=" Http://s3.51cto.com/wyfs02/M01/83/47/wKiom1duiU2wxA1cAADByI6Cdq0004.png "title=" 2016-06-25 21-37-58 screen. png "alt=" Wkiom1duiu2wxa1caadbyi6cdq0004.png "/>

So look like everything's hot? Perfect ~ ~ ~

However, there is no way to quit unless you press the CONTROL+Z key to force it out

So, I think the exit can also be achieved

if (id==0) {if (strcmp (my_argv[0], "exit") ==0) {exit (0);    }     ...    }      else {pid_t ret=waitpid (id,null,0);      if (strcmp (my_argv[0], "exit") ==0) {exit (0); }}} return 0;}

The result is:

650) this.width=650; "src=" Http://s1.51cto.com/wyfs02/M02/83/46/wKioL1duiwLx0ERIAAA7cmQlWiE896.png "title=" 2016-06-25 21-44-56 screen. png "alt=" Wkiol1duiwlx0eriaaa7cmqlwie896.png "/>

But then this exit is going to be amazing.

650) this.width=650; "src=" Http://s5.51cto.com/wyfs02/M02/83/47/wKiom1dui36yZqxBAAB2IyyRz44025.png "title=" 2016-06-25 21-47-02 screen. png "alt=" Wkiom1dui36yzqxbaab2iyyrz44025.png "/>

It took two cd,pwd operations, but exit has to be executed three times to exit, why?

So in order to debug I print analysis of the ID of the process and the ID of the parent process for all instructions executed

650) this.width=650; "src=" Http://s2.51cto.com/wyfs02/M02/83/47/wKiom1dujdXASlAmAACJcz_qrhM324.png "title=" 2016-06-25 21-57-00 screen. png "alt=" Wkiom1dujdxaslamaacjcz_qrhm324.png "/>650) this.width=650;" src= "http:// S4.51cto.com/wyfs02/m02/83/47/wkiom1dukvcg_gjyaafcozhcubw358.png "title=" screen Shot 2016-06-25 at 22.11.24.png "alt = "Wkiom1dukvcg_gjyaafcozhcubw358.png"/>


Conclusion:

LS: The first child process created terminates after executing EXECVP

Cd.. The second time the child process is created does not terminate when the chdir is executed

Cd.. The child process that is created the third time its parent process is the second child process created and does not terminate

When the exit is executed, it is terminated from the top to the outside, and then exits the entire program.

Improvement Program:

Write a function that is executed by the CD to the parent process

#include  <stdio.h> #include  <pwd.h> #include  <sys/types.h> #include  < unistd.h> #include  <string.h> #include  <stdlib.h>void prompt () {  struct  passwd * p1;  char username[64];  char hostname[256];   char pathname[1024];  //Get user name   p1=getpwuid (getuid ());   //Get path   &NBSP;GETCWD (pathname,sizeof (pathname));   //gets the hostname---returns 0 correct   if (gethostname (hostname,sizeof ( hostname) ==0)   {    printf ("[diy %[email protected]%s:%s ]", p1- >pw_name,hostname,pathname);   }  else  {    printf ("[DIY  %[email protected]:%s ] ", p1->pw_name,pathname);   }  if (Geteuid () ==0)   {    printf ("#");  }  else  {    &NBSP;PRINTF ("$"); &NBSP;&NBSP;}} Int main () {  while (1)   {    prompt ();     Fflush (stdout);     char buf[1024];    memset (Buf,0,sizeof (BUF));     size_t size=read (0,buf,sizeof (BUF)-1);         if (size>0)     {      buf[size-1]= ';     }   // printf ("%s\n", buf);    char *p=buf;     int i=0;    char * my_argv[64]={0};     my_argv[0]=p;    while (*p!=0)     {       if (*p== '   ')       {        *p= '         ++p;        my_ '; argv[++i]=p;      }      else      {         ++p;      }    }     pid_t id=fork ();     if (id==0)     {      if (strcmp (my_argv[0], "exit") ==0)       {        exit (0);      }       if (strcmp (my_argv[0], "CD") ==0)       {          exit (0);      }      else  &NBSP;&NBSP;&NBSP;&NBSP;&NBSP;{&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;EXECVP (MY_ARGV[0],MY_ARGV);       }    }    else     {    &Nbsp; pid_t ret=waitpid (id,null,0);      if (strcmp (my_argv[0], "CD") ==0)        {        chdir (my_argv[1]);        }      if (strcmp (my_argv[0], "exit") ==0 )       {       exit (0);       }    }  }  return 0;}

Results:

650) this.width=650; "src=" Http://s2.51cto.com/wyfs02/M00/83/46/wKioL1dukv2yavyXAABjovQmLPY644.png "title=" 2016-06-25 22-18-15 screen. png "alt=" Wkiol1dukv2yavyxaabjovqmlpy644.png "/>

This article from "Momo is spicy moe" blog, please be sure to keep this source http://momo462.blog.51cto.com/10138434/1792908

Write a mock shell under Linux

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.