从命令行到Shell Lab
简单的Linux命令
安装好ubuntu桌面版的虚拟机以后,现在让我们打开Linux终端 :

现在开始敲命令吧(由gpt生成)
pwd - 显示当前工作目录的路径。这可以帮助你确定你当前在哪个目录下工作。
pwdls - 列出当前目录下的文件和子目录。
lscd - 切换目录。你可以使用cd命令进入其他目录。
cd /path/to/directorymkdir - 创建新目录。
mkdir new_directorytouch - 创建新文件。
touch new_file.txtrm - 删除文件或目录。请谨慎使用,因为这是一个有风险的命令。
rm file.txtcp - 复制文件或目录。
cp file.txt /path/to/destinationmv - 移动文件或目录,也可用于重命名文件。
mv file.txt new_name.txt
以上的内容是最基本的命令行,我现在再看一个我们之后会使用的命令
echo- 输出输入的参数
echo ICS

此外你可以查看面试常考的Linux命令
从命令行到Shell Lab
我们敲命令的这个终端运行的其实就是一个shell程序,什么是shell呢?我们不妨回到前面这张图
先并不给出明确的shell的定义,但可以综合前面的内容看到一些shell的特性
首先shell接受命令的输入,执行程序,实现某些功能。
其次shell是运行在OS上的程序,shell会调用OS提供的syscall。
以echo命令为例子
shell会解释用户输入的命令,分析出命令名称(
echo)和参数(ICS)shell通过syscall向OS发出请求,以执行
echo(echo也是一个运行在OS上的应用程序)。执行
echo程序,echo调用syscall,然后OS会负责将指定的文本输出到终端。
写一个最简单的shell
现在让我们在Linux的命令行用C语言写一个最简单的支持echo和exit 命令的shell
1. 建议先学习C语言或者阅读下小节必要的C语言
2. 如果你是Mac或者Win的WSL的使用者,可以直接命令行完成下面的步骤
在终端,创建shell.c
vim shell.c在vim里写(复制)下面的代码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#define MAX_COMMAND_LENGTH 100
int main() {
char command[MAX_COMMAND_LENGTH];
while (1) {
printf("$ ");
fgets(command, sizeof(command), stdin);
// 去除命令末尾的换行符
command[strcspn(command, "\n")] = '\0';
if (strcmp(command, "exit") == 0) {
// 如果用户输入的是"exit"命令,退出shell
break;
} else if (strncmp(command, "echo ", 5) == 0) {
// 如果用户输入的是"echo"命令
// 创建子进程执行命令
pid_t child_pid = fork();
if (child_pid == 0) {
// 子进程中执行echo命令
execl("/bin/echo", "echo", command + 5, NULL);
// 如果execl执行失败,打印错误消息
perror("exec");
exit(1);
} else if (child_pid > 0) {
// 等待子进程结束
wait(NULL);
} else {
perror("fork");
}
} else {
// 对于其他不支持的命令,打印错误消息
printf("Unsupported command: %s\n", command);
}
}
return 0;
}
退出vim,终端gcc编译shell.c
gcc -o shell shell.c 这个命令的含义是:
gcc:这是GNU编译器的命令。-o shell:这部分指定了输出文件的名称,即编译后生成的可执行文件的名称将是shell。shell.c:这是要编译的源文件的名称,C程序文件名为shell.c。
终端执行
shell程序
./shell让我们来看看最终的效果

好的,这个shell实现echo和exit这两个功能,如果我不使用 exit 命令,这个小shell将一直执行下去。虽然
你可能还不能完全看懂上面
shell.c的逻辑还不了解
fork和execl这些syscall函数的使用还不太了解Linux的文件路径,比如
execl("/bin/echo", "echo", command + 5, NULL);这里面echo的执行文件在/bin/echo
但是现在的你已经开始了系统编程(system programming) !
在这学期,你将更深入地学习系统知识,并最终在Shell Lab写出一个支持许多命令并考虑到许多问题(如并发)的Unix Shell!
Last updated