编写基本Shell
对于我的课,我必须创建一个类似于bash的基本shell,允许用户调用ls,sleep等命令。我正在寻找有关如何执行此操作的资源:教程,帮助文本,示例代码甚至只是一些关于如何入门的一般信息。 有没有人有链接或信息来帮助我?
glibc手册包含一些有关在shell中实现作业控制的有用信息: http : //www.gnu.org/software/libc/manual/html_node/Implementing-a-Shell.html#Implementing-a-Shell
这真的取决于你的shell有多简单。 如果您不需要工作控制(即背景)或管道,那么它非常简单。 这是一个例子:
#include #include #define MAX_LENGTH 1024 int main(int argc, char *argv[]) { char line[MAX_LENGTH]; while (1) { printf("$ "); if (!fgets(line, MAX_LENGTH, stdin)) break; system(line); } return 0; }
您可以使用CTRL-D退出上面的示例。 要添加内置命令(如exit或cd),您必须使用strtok()对该行进行标记,然后查看第一个标记。 这是添加了这些命令的更复杂的示例:
#include #include #include #include #ifdef _WIN32 #include #define chdir _chdir #else #include #endif #define MAX_LENGTH 1024 #define DELIMS " \t\r\n" int main(int argc, char *argv[]) { char *cmd; char line[MAX_LENGTH]; while (1) { printf("$ "); if (!fgets(line, MAX_LENGTH, stdin)) break; // Parse and execute command if ((cmd = strtok(line, DELIMS))) { // Clear errors errno = 0; if (strcmp(cmd, "cd") == 0) { char *arg = strtok(0, DELIMS); if (!arg) fprintf(stderr, "cd missing argument.\n"); else chdir(arg); } else if (strcmp(cmd, "exit") == 0) { break; } else system(line); if (errno) perror("Command failed"); } } return 0; }
您可以通过添加更多内置命令或通过支持诸如带有参数的cd之类的内容来更改到您的主目录来扩展它。 您还可以通过添加当前目录等信息来改进命令提示符。
作为旁注,添加命令历史记录和行编辑function的简单方法是使用GNU readline库。
我为HelenOS项目编写了一个非常基本的shell。 它具有以下function:
- 线路编辑/历史
- 在命令/可加载命令中进行编辑
- 搜索路径以查找外部命令
- 极其基本的脚本
- 将大多数GNU核心实用程序(从头开始)的实现简化为内置函数。
其中大部分是在一个围绕函数指针构建的非常简单的可重用框架上实现的。 至少,你需要一个内置的“退出”或“退出”,这样有人可以真正离开shell,加上’cd’和’pwd’。 内置的“导出”/“声明”也是有意义的。
您可以查看此处许可的代码(BSD)。 或者下载repo,它位于uspace / app / bdsh中。 我可以挖掘最后一个工作的Linux版本,在我移植它之前,如果你需要它。 最大的区别是HelenOS版本使用本土生成的行编辑器,task_spawn()而不是execve()/ posix_spawn()等。其余的是可移植的。 它最初的设计只是为了使function测试变得简单和互动。 我没有实施工作控制,因为它不需要。 然而,这可以通过简单的方式实现。
如果你想研究一个“真正的”shell,我强烈建议你看看dash
,你会发现它比直接进入bash代码要简单得多。
有趣的是,’bdsh’代表’ 脑死壳 ‘。
您可以查看BusyBox的一些非常小的shell实现。
如果您要开始,请尝试http://stephen-brennan.com/2015/01/16/write-a-shell-in-c/,并进一步了解详细信息http://www.gnu.org/software/libc /manual/html_node/Data-Structures.html#Data-Structures 。
此外,在学习如何使用C / C ++编写shell时,习惯于引用命令的手册页。
Bash自己提供的命令很少: cd
, pushd
, popd
,变量处理例程( set
和$x
),以及所有控制流项目,如循环和条件。 几乎所有其他命令都可以在$PATH
中找到。
除非赋值另有说明,否则忽略变量和控制流。 只需提供一个查看$PATH
的REPL并执行用户输入的任何内容(可能是通过posix_spawn()
)并传递命令行参数。
低球回答:
如果程序非常简单,那么可以使用命令“ system("putdesiredcommandhere");
”来执行简单的系统调用system("putdesiredcommandhere");
在程序中安装“ printf
”时,在stdio.h的帮助下进行简单的系统调用。
下面是小代码示例。
#include #include main () { system ("clear"); system ("echo this is an example of a basic system call"); printf ("just as you've always done.\n"); return 0; }
使用该方法,您可以将bash或csh脚本转录为ac程序。 它需要对脚本中的每一行使用系统调用。