计算机系统篇之异常控制流(7):利用 fork 和 execve 实现一个简易的 shell 程序
Author: stormQ
Created: Saturday, 29. August 2020 01:11PM
Last Modified: Monday, 31. August 2020 06:39PM
什么是 shell
shell
是一个交互型的应用级程序,它代表用户运行其他程序。
shell
执行一系列的读 / 求值(read / evaluate)步骤,然后终止。读步骤读取自用户的一个命名行。求值步骤解析命令行,并代表用户运行程序。
如何在前台执行其他程序
step 1: 实现ReadCommand
函数
ReadCommand
函数用于读取用户一整行的输入(以换行符作为结束)。具体实现为:
std::string ReadCommand()
{
std::printf("> ");
std::string cmd;
std::getline(std::cin, cmd);
return cmd;
}
注:语句std::getline(std::cin, cmd)
的作用为:从标准输入流std::cin
中提取字符存储到std::string
类型的变量cmd
中,直到遇到换行符时停止提取。另外,std::getline()
函数的其他版本可以通过第三个参数指定界定符。
注意: std::getline()
函数提取的结果不包括界定符。
step 2: 实现PraseCommand
函数
PraseCommand
函数用于解析用户输入。即从用户输入中分割参数(以(一个或多个)空格作为参数分隔符),并初始化参数列表。
PraseCommand
函数的第 1 个参数为用户输入的字符串,第 2 个参数指向参数列表的指针。参数列表为栈对象,并且参数数量限制在 128 个以内。
在初始化参数列表时,为了避免对参数列表中每个参数进行额外的内存分配、释放及拷贝开销,我们将用户输入字符串的所有空格(以空格作为参数的分隔符)都替换为 C 语言中字符串结束符\0
。
由于std::string
不会自动在字符串末尾插入\0
字符。所以,需要我们自己插入一个。
PraseCommand
函数的具体实现为:
bool PraseCommand(std::string& input_cmd, char **output_cmd)
{
if (input_cmd.empty())
{
return false;
}
input_cmd.insert(input_cmd.end(), 1, '\0