你是否好奇当你在终端输入 ls -l 并按下回车后,背后发生了什么?本文将带你深入 Linux进程 的世界,通过手动实现一个简易Shell,彻底搞懂进程创建、程序替换和等待等核心概念。即使你是小白,跟着步骤也能写出自己的Shell!
Shell是一个命令解释器,它接收用户输入的命令,创建进程去执行,并显示结果。实现一个Shell能让你深刻理解 Linux进程 的管理机制,特别是 fork系统调用、exec函数族 和进程等待。这不仅是操作系统的经典实践,也是提升编程能力的绝佳途径。
在动手之前,我们先快速回顾几个关键概念:
execlp()、execvp()。我们的Shell将遵循一个无限循环:
mysh> )wait() 等待子进程结束我们将用C语言实现。创建一个文件 myshell.c,然后逐步添加代码。
#include #include #include #include #include #define MAX_INPUT 1024#define MAX_ARGS 64int main() {char input[MAX_INPUT];char *args[MAX_ARGS];while (1) {printf("mysh> ");fflush(stdout);// 读取输入if (fgets(input, MAX_INPUT, stdin) == NULL) {break; // Ctrl+D 退出}// 去掉末尾换行符input[strcspn(input, "")] = 0;// 如果输入为空,继续if (strlen(input) == 0) {continue;}// 解析命令(简单按空格分割)int i = 0;char *token = strtok(input, " ");while (token != NULL && i < MAX_ARGS - 1) {args[i++] = token;token = strtok(NULL, " ");}args[i] = NULL; // execvp要求最后一个参数是NULL// 内置命令处理(例如 exit、cd)if (strcmp(args[0], "exit") == 0) {break;}if (strcmp(args[0], "cd") == 0) {if (args[1] == NULL) {chdir(getenv("HOME"));} else {if (chdir(args[1]) != 0) {perror("cd");}}continue;}// 创建子进程pid_t pid = fork();if (pid == 0) {// 子进程:执行命令if (execvp(args[0], args) == -1) {perror("exec");exit(EXIT_FAILURE);}} else if (pid > 0) {// 父进程:等待子进程结束int status;waitpid(pid, &status, 0);} else {perror("fork");}}return 0;} fgets 获取一行,并去除换行符。strtok 按空格分割,得到命令名和参数列表。exit 退出Shell,cd 切换目录(用 chdir 实现)。execvp,它会在PATH中搜索程序)执行命令。父进程用 waitpid 等待子进程结束。在终端中编译:
gcc myshell.c -o myshell 运行:
./myshell 尝试输入 ls -l、pwd、cd /tmp、exit 等命令,感受自己写的Shell!
这个简易Shell还有很多可以改进的地方:支持输入/输出重定向、管道、后台运行(&)、更复杂的解析(引号处理)等。但通过这个实践,你已经掌握了 Linux进程 的核心操作——fork系统调用 和 exec函数族。继续探索,你也能成为Linux编程高手!
原文链接:www.example.com | 转载请注明出处
本文由主机测评网于2026-03-02发表在主机测评网_免费VPS_免费云服务器_免费独立服务器,如有疑问,请联系我们。
本文链接:https://www.vpshk.cn/20260328266.html