实现的功能:
1重定向: < 、>、>>, dup2(oldfd,newfd),标准输入的文件描述符为0,标准输出的为1,标准错误输出的为2
2管道: | 也需要用到dup2(oldfd,newfd),标准输出用1,标准输入用0
3后台运行程序(&):父进程直接返回,不等待子进程结束
4shell内置命令:只实现cd
5tab键补全和上下键:需要用到readline库,sudo apt-get install libreadline6-dev安装好之后,编译时加上-lreadline
6ctrl+c不能中断程序: signal(SIGINT, SIG_IGN)用这个函数将ctrl+c忽略掉
7环境变量:将可执行文件放置在/bin目录下,命令执行时,系统会在$PATH路劲下寻找可执行的文件
8界面美观,尽量接近bash
下面是代码:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <dirent.h>
#include <signal.h>
#include <readline/readline.h>
#include <readline/history.h>
#include <pwd.h>
#define normal 0 //一般的命令
#define out_redirect 1 //输出重定向
#define in_redirect 2 //输入重定向
#define have_pipe 3 //命令中有管道
#define out_redirec 4 //命令中有>>
void do_cmd(int argcout, char arglist[100][256]); //执行arglist中保存的命令
int find_command(char *command); // 在当前目录,以及/bin、/use/bin下查找命令的可执行程序
void explain_input(char *buf, int *argcout, char arglist[100][256]); //解析buf中的命令,将每个选项存到arglist
char oldpwd[300]; //为实现cd -,用oldpwd来保存上个路径
int main(int argc, char **argv)
{
struct passwd *name;
signal(SIGINT, SIG_IGN);
int i, len;
int argcout = 0;
char arglist[100][256], temp[256], pwd[100];
char *buf = NULL, *s = NULL;
buf=(char *)malloc(sizeof(char)*256);
if( buf == NULL ){
perror("malloc failed");
exit(-1);
}
getcwd(oldpwd, sizeof(oldpwd)); //获取当前路径
while(1){
name = getpwuid(getuid());
getcwd(pwd, sizeof(pwd) - 1);
sprintf(temp, "[%s @myshell:\033[0;34m%s\033[0m]$ ", name->pw_name, pwd); //使输出更加美观
memset(buf,0,256);
s = readline(temp); //用readline()函数读取输入命令
add_history(s);
write_history(NULL);
strcpy(buf, s); //将命令拷贝到buf中
if ( strcmp(buf, "cd") == 0 || strcmp (buf, "cd ") == 0 ) {
//若命令中有cd,则默认为cd ~
strcat(buf, " ~");
}
len = strlen(buf);
len++;
buf[len++] = '\n';
buf[len] = '\0';
if( strcmp(buf,"exit") ==