minishell 程序
使用到的技术:创建子进程,进程替换,进程等待理解bash(命令行解释器)本身也是一个程序,在命令行解释器中输入ls,pwd,mv,cp等这些命令的时候,其实bash也是创建了一个子进程,让子进程去进程程序替换执行相应的命令程序。实现 3.1 从标准输入当中获取用户输入的命令 3.2 创建子进程,让子进程进行进程替换,执行刚刚从标准输入读进来的命令 3.3 父进程需要子进程进行进程程序替换的时候,父进程进行进程等待,防止子进程变成僵尸进程 图解:
char g_command
[1024
];
int Getcommand
()
{
printf
("[zs@localhost minishell]");
fflush
(stdout
);
memset
(g_command,
'\0', sizeof
(g_command
));//初始化
if
(fgets
(g_command, sizeof
(g_command
) -1, stdin
) == NULL
)
{
perror
("fgets perror");
return -1
;
}
printf
("%s\n", g_command
);
return 0
;
}
int ExecCommand
(char* argv
[])
{
//创建子进程
//让子进程进行程序替换
if
(argv
[0
] == NULL
)
{
printf
("ExecCommand failed\n");
return -1
;
}
pid_t pid
= fork
();
if
(pid
< 0
)
{
perror
("fork");
return -1
;
}
else if
(pid
== 0
)
{
//child --
>进程程序替换
execvp
(argv
[0
], argv
);
//如果调用了execvp,还能走到下面的逻辑,则表示替换失败了
//将没有替换成功的子进程杀掉
exit
(0
);
}
else
{
//father --
>进程等待,防止子进程变成僵尸进程
waitpid
(pid, NULL, 0
);
}
return 0
;
}
int Dealcommand
(char* command
)
{
//ls -l
==> ls 可执行程序 -l 传递给ls的命令行参数
//1. 切分读进来的字符串,区分一下什么是可执行程序
// 1.1切分出来的第一个字符串就是可执行程序
// 1.2后面的都是命令行参数进行切割
// 1.3用空格作为分隔符来进行切割
int argc
= 0
;
char* argv
[1024
] = {0
};
while
(*command
)
{
//判断当前的字符是否是空格 或者 \0,如不是就保存在char*
if
(!isspace
(*command
) && *command
!= '\0')
{
argv
[argc
] = command;
argc++
;
while
(!isspace
(*command
)&& *command
!= '\0')
{
command++
;
}
*command
= '\0';//将非字符的全部用\0代替
}
command++
;//向后寻找
}
argv
[argc
] = NULL
;
int i
= 0
;
for
(i
= 0
; i
< argc
; i++
)
{
printf
("%d:%s\n", i , argv
[i
]);
}
}
int main
()
{
while
(1
)
{
//1.获取用户数日的命令
if
(Getcommand
() == -1
)
{
continue;
}
//2.创建子进程
//3.让子进程进行程序替换
//4.进程等待
Dealcommand
(g_command
);
}
return 0
;
}
结果: