Make your own Linux-->shell

Source: Internet
Author: User
Tags strcmp

before starting the code, let's take a look at what a shell is. Shell English is also called the shell layer. In a computer, "system" software that "provides user interface", usually refers to the command parser of the command line interface. In general, this term refers to the program that provides access to the services provided by the kernel in the operating system. But the word also refers to the application software, or any other "software" on the periphery of a particular component ... Omit 300 words ...-----> Thanks for 36,000

Common Shell Categories:

      • BASH: is the GNU Bourne Again Shell, which is the default shell on the GNU operating system

      • Korn Shell: The development of the Bourne Shell, which is compatible with Bourne Shell (Bash) on most content

      • C Shell: The BSD version of Sun's shell

      • Z Shell:z is the last letter, the ultimate Shell. It integrates the critical features of Bash Ksh while adding its own unique features.


Look at where the shell is on the computer and what it uses

650) this.width=650; "Src=" Http://s5.51cto.com/wyfs02/M02/82/95/wKioL1dcG12DuAXKAADHHF1XCqk508.png-wh_500x0-wm_3 -wmp_4-s_3350446703.png "title=" Computer hardware and software components. png "alt=" wkiol1dcg12duaxkaadhhf1xcqk508.png-wh_50 "/>

This custom shell uses a multi-process approach, with interprocess communication using pipe (pipe).


directly on the code.

#include  <stdio.h> #include  <stdlib.h> #include  <string.h> #include  < unistd.h> #include  <sys/wait.h> #include  <sys/types.h> #include  <fcntl.h># Include <sys/stat.h> #include  <errno.h>typedef struct __info{charbuf[1024];// User input Information unsigned intpipenum;//count the number of pipelines}info;//record host name default localhoststatic char hostname[1024] =   "localhost";//Error hint Int sys_err (const char* err) {perror (err); exit (exit_failure);} Message hint Void display () {static unsigned int sum = 1;//record input count char buf[1024]  = { 0 };//gets the current path GETCWD (buf, sizeof (BUF));p rintf ("[#%d#%[email protected]%s]> ",  sum, hostname, buf); sum++;} /* *  user Input content processing  *  @reminder  info  incoming structure  * return: *  success: Exit_ success *  failure: Exit_failure*/int handle (info* info) {if (null == info) {priNTF ("func %s err: [null == info]\n",  __function__); exit (Exit_failure); char* p = info->buf;//count the number of pipes while (null !=  (P&NBSP;=&NBSP;STRCHR (p,  ' |))) {info->pipenum++;p + +;} p = info->buf;//Remove Carriage return if (null !=  (P&NBSP;=&NBSP;STRCHR (p,  ' \ n '))) {*p =  ' ‘;} return exit_success;} Character Substitution int replate (char* str, const char src, const char des) {if (NULL &NBSP;==&NBSP;STR) {printf ("func %s error: [null == str]\n",  __function__); exit ( Exit_failure);} Char* p =str;while (*p) {if (src == *p) {*p = des;} p++;} return exit_success;} Command parsing Int resolverun (CHAR*&NBSP;PTR,&NBSP;CHAR**&NBSP;ARGV) {if (null == ptr | | &NBSP;NULL&NBSP;==&NBSP;ARGV) {printf ("func %s error:[null == ptr | |  null == argv]\n ",  __function__); exit (exit_failure);} Int i = 0;iNt fd;char* inptr = null;char* p = strtok_r (ptr,  " ", & INPTR) Argv[i++] = p;while (null !=  (P = strtok_r (null,  " ", & INPTR))) {argv[i++] = p;} Determine if there is a redirect I--;while (i) {if (0 == strcmp (argv[i],  > ")) {Fd = open (argv[i+1], o_ wronly | o_creat | o_trunc, 0644), if (0&NBSP;&GT;&NBSP;FD) {Sys_err ("func  Resolverun ()  open error:  ");} Backup output to 1023 descriptor Dup2 (stdout_fileno, 1023);d up2 (Fd, stdout_fileno); Argv[i] = null;close (FD); /Find First >int n = 1;while (n < i) {if (0 == strcmp (argv[n],  >)) { Argv[n] = null;break;} n++;} break;} if (0 == strcmp (argv[i],  ">>")) {Fd = open (argv[i+1], o_append| O_creat| o_wronly, 0644); if (0&NBSP;&GT;&NBSP;FD) {Sys_err ("Func resolverun ()  open error: ");} Dup2 (stdout_fileno, 1023);d up2 (Fd, stdout_fileno); Argv[i] = null;close (FD);//Find the first >int n =  1;while (n < i) {if (0 == strcmp (argv[n],  >>)) {Argv[n] = null ; break;} n++;} break;} if (0 == strcmp (argv[i],  "<")) {Fd = open (argv[i+1], o_rdonly); if (0 > &NBSP;FD) {Sys_err ("Func resolverun ()  open error: ");} Char buf[1024] = { 0 };int len = 0;while (0 !=  (len =  read (fd, buf, sizeof (BUF))) {if (0 > len) {Sys_err ("Func resolverun ()   read error:  ");} Write (Stdin_fileno, buf, len); Bzero (Buf, sizeof (BUF));} Outputs a terminator to the end -1PUTC ( -1, stdin_fileno); Argv[i] = null;close (FD);//Find the first >int n =  1;while (n < i) {if (0 == strcmp (argv[n],  <)) {argv[n] = null; break;} n++;} break;} i--;} return exit_success;} Split command int&Nbsp;seve (Info* info) {if (null == info) {printf ("func %s err: [null ==  Info]\n ",  __function__); exit (exit_failure);} Determines whether the empty data if (0 == * (info->buf)) {return exit_success;} pid_t pid;pid_twpid;char buf[1024] = { 0 };char* p = buf;char*  inptr = null;int i = 0;int fd[2];char* argv[256] = {null};/ /Copy the original data memcpy (buf, info->buf, sizeof (BUF));//Processing tab replate (buf,  ' \ t ',  '   ');//Processing ' Number replate (buf,  ' \ ',  '   ');//Processing "number replate (buf,  ' \" ',  '   '); for (i = 0;  i <= info->pipenum; i++) {if (0 == i) {p = strtok_r (p,  "|", &NBSP;&AMP;INPTR);} Else{p = strtok_r (null,  "|",  &inptr);} Initialize Bzero (argv, sizeof (argv));//Command parsing resolverun (P,&NBSP;ARGV);//Determine if the built-in command if (0 == i & &AMP;&NBSP;0&NBSP;==&NBSP;STRCMP ("CD", Argv[0]) {if (0 > chdir (argv[1])) {     //determines the type of error, prompting user information       if (Enoent == errno) {printf ("-sea_bash: cd: %s:  does not have that file or directory \ n",  argv[1] );} if (Eacces == errno) {printf ("-sea_bash: cd: %s:  permissions not enough \ n",  argv[1]);} if (Enotdir == errno) {printf ("-sea_bash: cd: %s:  is not a directory \ n",  argv[1]);}} return exit_success;} Else if (0 == i && 0 == strcmp ("pwd",  argv[0])) {char buf[ 1024]&NBSP;=&NBSP;{&NBSP;0&NBSP;};GETCWD (buf, sizeof (BUF));                 //get current working directory Buf[strlen (buf)] =  ' \ n ';                  //add newline write at end (STDOUT _fileno, buf, strlen (BUF))   //prints the current path to the screen return exit_success;                      //successfully ended}else if (0 &NBSP;==&NBSP;I&NBSP;&AMP;&AMP;&NBSP;0&NBSP;==&NBSP;STRCMP ("hostname",  argv[0])) {//empty bzero (hostname, &NBSP;SIZEOF (hostname))          //the original hostname empty memcpy (hostname,  argv[1], strlen (argv[1]));    //reset hostnamereturn exit_success;} Else if (0 == i && 0 == strcmp ("Exit",  argv[0])) {//End process printf (" --------------------God-bey-----------------------------\ n "), Kill (Getppid (),  sigint);             //send end signal to this process EXIT (exit_success);                  //Direct Process Exit}//Create pipeline if (0 >  pipe (FD)) {Sys_err ("Func seve ()  pipe error: ");} Pid = fork (); if (0 > pid) {Sys_err ("Func seve () &Nbsp;fork error: ");} Else if (0 == pid) {close (fd[0]);         //child process closes read-side dup2 ( 1022, fd[0]);     //directs the read end multiplicity of the previous pipe to Fd[0]close (1022);           //Close the read end of the previous signal to avoid the existence of more than one read end of the 1022 break;                 //out}//to restore the output descriptor dup2 (1023, stdout_fileno);//Save the read end to the next process using Dup2 (fd[0 ], 1022);         //the backup pipeline reads to 1022 for the next pipeline to use Close (fd[1]);              //closing the Write End Close (fd[0]);              //because it has been backed up, you can directly close the fd[0]}//subprocess process if (i != info- >pipenum+1) {if (0 != info->pipenum) {if (I == info->pipenum) {close (fd[1]);d up2 (Fd[0] ,  stdin_fileno);} if (0 == i) {dup2 (Fd[1], stdout_fileno);} Else{dup2 (Fd[0], stdin_Fileno);d up2 (Fd[1], stdout_fileno);}} EXECVP (ARGV[0],&NBSP;ARGV);p rintf ("-sea_bash: %s: command not found\n",  argv[0]); exit (exit_failure);} The parent process waits for the child process to end if (i == info->pipenum+1) {do{wpid = waitpid ( -1, null, wnohang); 0 < wpid) {i--;}} while (0 < i);} return exit_success;} Entranceint main (int argc, char* argv[]) {info info = {{0}, 0};for (;;) {display ();//Get user input fgets (info.buf, sizeof (INFO.BUF),  stdin);//Information processing handle (&info);//Split command Seve (& info);//emptying Initialization bzero (&info, sizeof (info));} return exit_success;}


This article is from the "Sea" blog, be sure to keep this source http://lisea.blog.51cto.com/5491873/1788014

Make your own Linux-->shell

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.