Look at where the shell is on the computer and what it uses
650) this.width=650; "Src=" Http://s4.51cto.com/wyfs02/M00/82/96/wKiom1dcG0ySUTQpAADHHF1XCqk040.png-wh_500x0-wm_3 -wmp_4-s_1032667663.png "title=" Computer hardware and software components. png "alt=" wkiom1dcg0ysutqpaadhhf1xcqk040.png-wh_50 "/>
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;>&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;>&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;&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 & &&NBSP;0&NBSP;==&NBSP;STRCMP ("CD", Argv[0]) {if (0 > chdir (argv[1])) {//Judgment error type, prompt 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 a newline write (Stdout_fileno, buf, strlen (BUF)) at the end of the //,//print the current path to the screen return exit_success;//the successful end}else if (0 == i && 0 == strcmp ("hostname", argv[0]) {//emptying bzero ( HOSTNAME,&NBSP;SIZEOF (hostname));//Empty the original hostname memcpy (Hostname, argv[1], strlen (argv[1]));// Reset hostnamereturn exit_success;} Else if (0 == i &&amP;&NBSP;0&NBSP;==&NBSP;STRCMP ("Exit", argv[0])) {//End Process printf ("-------------------- God-bey-----------------------------\ n "), Kill (Getpid (), sigint),//Send the end signal to the 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 () fork error:");} Else if (0 == pid) {close (fd[0]);//Sub-process close read dup2 (1022, fd[0]);//Direct read end multiplicity of the previous pipe to Fd[0]close (1022) ;//Close 1022 read end of the previous signal, avoid the existence of multiple read end break;//out}//restore output descriptor dup2 (1023, stdout_fileno);//Save the read end to the next process using Dup2 (fd[0], 1022); Close (fd[1]); Close (fd[0]);} The child process handles if (i != info->pipenum+1) {//No pipe command 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&Nbsp;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;} Int 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;}