参考:
https://blog.youkuaiyun.com/studyhardi/article/details/89763358
https://blog.youkuaiyun.com/OCTODOG/article/details/70942194
1、先是最简单的,能够执行并输出
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/wait.h>
#include <fcntl.h>
#include <stdlib.h>
//https://blog.youkuaiyun.com/studyhardi/article/details/89763358
//https://blog.youkuaiyun.com/OCTODOG/article/details/70942194
char prefix[] = "MyShell> ";
char *argv[8+1];
void do_parse(char *buf){
char *s = NULL;
int i;
s = strtok(buf," ");
for(i=0;i<8&&s != NULL;i++){
argv[i] = s;
s = strtok(NULL," ");
}
argv[i] = NULL;
}
void do_execute(void){
pid_t pid = fork();
if(pid < 0){
exit(1);
}else if(pid == 0){
execvp(argv[0],argv);
}
else{
waitpid(pid,NULL,0);
}
}
int main(){
char buf[1024] = {0};
for(;;){
write(STDOUT_FILENO,prefix,strlen(prefix));
scanf("%[^\n]%*c",buf);//https://blog.youkuaiyun.com/jeffasd/article/details/80705487
do_parse(buf);
do_execute();
}
}
2、实现管道 |
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/wait.h>
#include <stdlib.h>
//https://blog.youkuaiyun.com/studyhardi/article/details/89763358
//https://blog.youkuaiyun.com/OCTODOG/article/details/70942194
char prefix[] = "MyShell> ";
char* proc[8];
int proc_count=0;
char *argv[8][8+1];
void sighandle(int signum){
//printf("recv %d signal, process %d\n",signum,getpid());
}
void do_parse(char *buf){
char *s = NULL;
int i,j;
s = strtok(buf,"|");
for(proc_count=0;proc_count<8&&s!= NULL;proc_count++){
proc[proc_count] = s;
s = strtok(NULL,"|");
}
for(i=0;i<proc_count;i++){
s = strtok(proc[i]," ");
for(j=0;j<8&&s!=NULL;j++){
argv[i][j] = s;
s = strtok(NULL," ");
}
argv[i][j] = NULL;
}
}
void do_execute_child(pid_t parent_pid){
int i;
pid_t pid;
for(i=0;i<proc_count;i++){
int fd[2];
pipe(fd);
pid = fork();
if(pid < 0){
exit(1);
}else if(pid == 0){
close(fd[1]);
dup2(fd[0],STDIN_FILENO);
}else{
close(fd[0]);
dup2(fd[1],STDOUT_FILENO);
execvp(argv[i][0],argv[i]);
}
}
if(pid == 0){
char buf[1024];
int l;
while( (l=read(STDIN_FILENO,buf,sizeof(buf))) > 0){
write(STDOUT_FILENO,buf,l);
}
kill(parent_pid,SIGALRM);//由最后一个子程序唤醒曾曾曾曾曾...祖父
}
exit(0);
}
void do_execute(void){
int i;
pid_t pid;
pid = fork();
if(pid < 0){
return;
}else if(pid == 0){
do_execute_child(getppid());
}else{
pause();//阻塞,等待唤醒
}
}
int main(){
signal(SIGALRM,sighandle);
signal(SIGCHLD,SIG_IGN);
char buf[1024] = {0};
for(;;){
write(STDOUT_FILENO,prefix,strlen(prefix));
scanf("%[^\n]%*c",buf);//https://blog.youkuaiyun.com/jeffasd/article/details/80705487
do_parse(buf);
do_execute();
}
}
3、实现重定向 >log 以及 2>&1
未完待续...