?? minishell.c
字號:
#include "minishell.h"char *lookupPath(char **,char **); //查找命令行中所包含的可執行文件在哪條路徑下,返回該絕對路徑int parseCommand(char *,struct command_t *); //對命令行中的參數進行分割,分別存入argv[]數組中int parsePath(char **); //將環境變量PATH中的路徑根據“:”進行分割void printPrompt(); //打印提示符,以便user輸入命令行char *pathv[MAX_PATHS]; //包含環境變量PATH中所有路徑的數組int main(){ int i; int pid; int status; FILE *fid; char cmdline[LINE_LEN]; //包含命令行的參數 struct command_t command; char path_cp[MAX_PATH_LEN]; if(!parsePath(pathv)) { //解析環境參數PATH中路徑,如果失敗則輸出錯誤信息提示 printf("Path parse failed"); exit(0); } while(1) //設置死循環可以使user重復輸入命令 { printPrompt(); //輸出提示符 fgets(cmdline,LINE_LEN,stdin); //將命令行的參數輸入到cmdLine中 if(*cmdline == '@') exit(0); //如果是命令是"@"則退出該程序中的死循環 parseCommand(cmdline,&command); //解析命令 command.argv[command.argc] = NULL; //命令行參數的數組最后以NULL結尾 command.name = lookupPath(command.argv, pathv);//查找命令行中可執行文件所在的目錄路徑 if(command.name == NULL) { //如果未找到,則輸處未找到的提示進入下一個命令的執行 continue; } if((pid = fork()) == 0) //創建一個子進程 {//子進程執行下列操作
//execv()的函數實例:execv("/bin/ls",NULL) strcpy(path_cp,command.name); strcat(path_cp,"/"); strcat(path_cp,command.argv[0]); //將path_cp設定為execv()函數指定的路徑格式,加上/filename if( execv(path_cp,command.argv)<0) printf("err!\n");
//如果進程執行發生錯誤則顯示錯誤提示 } else //父進程執行該操作,等待子進程執行完成 wait(&status); } return 0; }int parseCommand(char *cLine,struct command_t *cmd){ //命令解析 int argc; char **clPtr; clPtr = &cLine; argc = 0; cmd->argv[argc] = (char *)malloc(MAX_ARG_LEN); while((cmd->argv[argc] = strsep(clPtr,WHITESPACE)) != NULL) { //strsep()函數根據WHITESPACE的值將clPtr(命令行)分隔開,即根據","、空格和回車分開命令參數 cmd->argv[++argc] = (char *)malloc(MAX_ARG_LEN); } cmd->argc = argc - 1; cmd->name = (char *)malloc(sizeof(cmd->argv[0])); strcpy(cmd->name,cmd->argv[0]); //將文件名存入結構的command.name中 return 1;}void printPrompt(){ //打印提示符,"主機名$" char *promptString; promptString = HOSTNAME; printf("%s$",promptString);}int parsePath(char *dirs[]){ //路徑解析 char *pathEnvVar; char *thePath; int i; char *str = ":"; for(i = 0; i<MAX_PATHS; i++) pathv[i] = NULL; //進行數組的初始化 pathEnvVar = (char *) getenv("PATH"); //char *getenv(const char *name);可以得到環境變量 thePath = (char *) malloc(strlen(pathEnvVar) + 1); strcpy(thePath,pathEnvVar); //將環境變量中的目錄路徑輸入到thePath中 i = 0; while((pathv[i++] = strsep(&thePath,str)) != NULL); //將環境變量中的路徑根據":"進行分割,存入pathv[]數組中 return 1;}char *lookupPath(char **argv, char *div[]){ //獲得命令行中可執行文件所在的目錄路徑 int i; char *result; char pName[MAX_PATH_LEN]; DIR *pDir = NULL; struct dirent *pDirent = NULL; if(*argv[0] == '/') { //命令本身就是絕對路徑,則直接返回 result = argv[0]; return result; } else if(*argv[0] == '.') { //是當前目錄下的 result = "/usr/project"; return result; } else { //相對路徑 for(i = 0; i < MAX_PATHS; i++) { //對每個目錄進行查找,是否存在該可執行文件 if(div[i] == NULL) break; //查找完畢則跳出,否則會出現段錯誤 pDir = opendir(div[i]); //打開目錄 if(pDir) { while(pDirent = readdir(pDir)) { //對目錄中的文件進行讀,當讀完后則返回0值并跳出循環 if(strlen(pDirent->d_name) != strlen(argv[0])) { //比較長度,不同則繼續查找下一個文件 continue; } if(!strncmp(pDirent->d_name, argv[0], pDirent->d_reclen)) { //對兩個文件名進行比較 result = div[i]; return result; } } } } fprintf(stderr, "%s:command not found\n",argv[0]); //沒有找到則返回未找到命令的信息 return NULL; } }
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -