Linux下的簡易shell實現
阿新 • • 發佈:2018-11-02
- Linux系統的shell作為作業系統的外殼,為使用者提供使用作業系統的介面。
- 它是命令語言、命令解釋程式及程式設計語言的統稱。
- 相當於bash的一個子程序,父程序等待,子程序進行程式替換。
- shell充當一個橋樑:將使用者的命令翻譯給核心(kernel)處理;同時,將核心的處理結果翻譯給使用者。
- shell在你成功地登入進入系統後啟動,並始終作為你與系統核心的互動手段直至你退出系統。
- 你係統上的每位使用者都有一個預設的shell,每個使用者的預設shell在系統裡的/etc/passwd檔案裡被指定。
寫一個簡易的shell需要以下操作:
- 獲取命令列
- 解析命令列(strtok:將字串打散)
- 建立一個子程序(fork)
- 替換子程序(execve)
- 父程序等待子程序(wait)
程式碼實現:
#include<stdio.h> #include<unistd.h> #include<sys/wait.h> #include<string.h> #include<stdlib.h> #include<sys/stat.h> #include<sys/types.h> #include<ctype.h> #include<fcntl.h> int main() { while(1) { printf("[Myshell]>"); fflush(stdout); //解析輸入到shell上的字串 ls -a -l char buffer[1024]; int read_size = read(1, buffer, sizeof(buffer)-1); if (read_size > 0) { buffer[read_size - 1] = 0; } char* shell_argv[32] = {NULL}; int shell_index = 0; char* start = buffer; while (*start != '\0') { while (*start != '\0' && isspace(*start)) { start++; } } //建立子程序來exec pid_t pid = vfork(); if (pid < 0) { printf("vfork failure\n"); exit(1); } else if (pid == 0) { //考慮重定向 > //在字串陣列中找重定向標誌 int i = 0; int flag = 0; for (; shell_argv[i] != NULL; ++i ) { if (strcmp(">", shell_argv[i]) == 0) { flag = 1; break; } } int copyFd; shell_argv[i] = NULL; if (flag) { if (shell_argv[i+1] == NULL) { printf("command error\n"); exit(1); } close(1); int fd = open(shell_argv[i+1], O_WRONLY | O_CREAT, 0777 ); copyFd = dup2(1, fd); } execvp(shell_argv[0], shell_argv); if (flag) { close(1); dup2(copyFd, 1); } exit(1); } else //father process { int status = 0; int ret = waitpid(pid, &status, 0); if (ret == pid) { if (WIFEXITED(status)) { // printf("exitCode is %d\n", WEXITSTATUS(statu s)); } else if (WIFSIGNALED(status)) { printf("signal is %d\n", WTERMSIG(status)); } } } } return 0; }