shell执行的命令,通常有两种 第三方提供的,对应在磁盘的可执行程序(由子程序执行) shell内部,自己实现的方法,由自己(父进程)来执行 有些命令是会影响shell本身的 如:cd、export(添加环境变量) 思路: 获取命令行 解析命令行 建立一个子进程 – fork 替换子进程 – execvp 父进程等待子进程tuichu – wait 实现:
# include <stdio.h>
# include <string.h>
# include <stdlib.h>
# include <unistd.h>
# include <sys/types.h>
# include <sys/wait.h> # define NUM 1024
# define SIZE 32
# define SEP " " char cmd_line[ NUM] = { 0 } ;
char * g_argv[ SIZE] = { NULL } ;
char g_valbf[ NUM] ;
int main ( )
{ while ( 1 ) { printf ( "[SnowK@localhost minishell]# " ) ; fflush ( stdout ) ; if ( fgets ( cmd_line, sizeof cmd_line, stdin ) == NULL ) { continue ; } cmd_line[ strlen ( cmd_line) - 1 ] = '\0' ; int index = 1 ; g_argv[ 0 ] = strtok ( cmd_line, SEP) ; if ( strcmp ( g_argv[ 0 ] , "ls" ) == 0 ) { g_argv[ index++ ] = "--color=auto" ; } if ( strcmp ( g_argv[ 0 ] , "ll" ) == 0 ) { g_argv[ 0 ] = "ls" ; g_argv[ index++ ] = "-l" ; g_argv[ index++ ] = "--color=auto" ; } while ( g_argv[ index++ ] = strtok ( NULL , SEP) ) ; if ( strcmp ( g_argv[ 0 ] , "export" ) == 0 && g_argv[ 1 ] != NULL ) { strcpy ( g_valbf, g_argv[ 1 ] ) ; putenv ( g_valbf) ; continue ; } if ( strcmp ( g_argv[ 0 ] , "cd" ) == 0 ) { if ( g_argv[ 1 ] != NULL ) { chdir ( g_argv[ 1 ] ) ; continue ; } } pid_t id = fork ( ) ; if ( id == 0 ) { printf ( "child start\n" ) ; printf ( "----------------------------\n" ) ; execvp ( g_argv[ 0 ] , g_argv) ; exit ( 1 ) ; } int status = 0 ; int ret = waitpid ( id, & status, 0 ) ; if ( ret > 0 ) { printf ( "child success, exit code:%d\n" , WEXITSTATUS ( status) ) ; printf ( "----------------------------\n" ) ; } } return 0 ;
}