编写基本Shell

Bob*_*y S 21 c bash shell

对于我的课,我必须创建一个类似于bash的基本shell,允许用户调用ls,sleep等命令.我正在寻找有关如何执行此操作的资源:教程,帮助文本,示例代码甚至只是一些关于如何入门的一般信息.有没有人有链接或信息来帮助我?

jco*_*and 11

这实际上取决于你的shell有多简单.如果您不需要工作控制(即背景)或管道,那么它非常简单.这是一个例子:

#include <stdio.h>
#include <stdlib.h>

#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;
}
Run Code Online (Sandbox Code Playgroud)

您可以使用CTRL-D退出上面的示例.要添加内置命令(如exitcd),您必须使用strtok()对行进行标记,然后查看第一个标记.这是添加了这些命令的更复杂的示例:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>

#ifdef _WIN32
#include <windows.h>
#define chdir _chdir

#else
#include <unistd.h>
#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;
}
Run Code Online (Sandbox Code Playgroud)

您可以通过添加更多内置命令或支持诸如带有out参数的cd之类的内容来更改主目录.您还可以通过添加当前目录等信息来改进命令提示符.

作为旁注,添加命令历史和行编辑功能的简单方法是使用GNU readline库.


小智 5

我为HelenOS 项目编写了一个非常基本的 shell 。它具有以下特点:

  • 行编辑/历史记录
  • 内置命令/可加载命令
  • 查找外部命令的搜索路径
  • 极其基本的脚本编写
  • 将大多数 GNU 核心实用程序的实现简化为内置函数(从头开始完成)。

其中大部分是在围绕函数指针构建的非常简单的可重用框架上实现的。至少,您需要一个内置的“exit”或“quit”,以便某人实际上可以退出 shell,再加上“cd”和“pwd”。内置的“导出”/“声明”也是有意义的。

您可以在此处查看许可的代码(BSD)。或者下载存储库,它位于 uspace/app/bdsh 中。如果您需要的话,我可能可以在我移植之前找到最后一个可用的 Linux 版本。最大的区别是 HelenOS 版本使用了自制的行编辑器,task_spawn() 而不是 execve() / posix_spawn() 等。其余的都是可移植的。它最初的设计只是为了使功能测试变得简单和交互式。我没有实施作业控制,因为不需要。然而,这可以轻松实现。

如果您想学习“真正的”shell,我强烈建议您查看dash,您会发现它比直接深入了解 bash 代码更容易掌握。

有趣的是,“bdsh”代表“脑死亡贝壳”。