编写基本Shell

时间:2011-01-24 23:25:08

标签: c bash shell

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

6 个答案:

答案 0 :(得分:24)

glibc手册包含一些有关在shell中实现作业控制的有用信息:http://www.gnu.org/software/libc/manual/html_node/Implementing-a-Shell.html#Implementing-a-Shell

答案 1 :(得分:10)

这实际上取决于你的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;
}

您可以使用CTRL-D退出上面的示例。要添加内置命令,例如退出 cd ,您必须使用 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;
}

您可以通过添加更多内置命令或通过支持 cd 之类的内容来扩展此功能,并使用out参数更改为您的主目录。您还可以通过添加当前目录等信息来改进命令提示符。

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

答案 2 :(得分:4)

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

  • 线路编辑/历史
  • Buit in commands / loadable commands
  • 搜索路径以查找外部命令
  • 极其基本的脚本
  • 将大多数GNU核心实用程序(从头开始)的实现简化为内置函数。

大多数是在一个围绕函数指针构建的非常简单的可重用框架上实现的。至少,你需要一个内置的“退出”或“退出”,这样有人可以真正脱离外壳,加上'cd'和'pwd'。内置的“导出”/“声明”也是有意义的。

您可以查看已获得许可的代码(BSD)here。或者下载repo,它位于uspace / app / bdsh中。我可以挖掘最后一个工作的Linux版本,在我移植它之前,如果你需要它。最大的区别是HelenOS版本使用本土生成的行编辑器,task_spawn()而不是execve()/ posix_spawn()等。其余的是可移植的。它最初的设计只是为了使功能测试变得简单和互动。我没有实施工作控制,因为它不需要。然而,这可以通过简单的方式实现。

如果你想研究一个'真正'的shell,我强烈建议你看dash,你会发现它比直接深入bash代码要简单得多。

有趣的是,'bdsh'代表'脑死壳'。

答案 3 :(得分:2)

对于一些非常小的shell实现,你可以查看BusyBox

答案 4 :(得分:0)

Bash自己提供的命令很少:cdpushdpopd,变量处理例程(set$x),以及所有命令控制流项目,如循环和条件。几乎所有其他命令都可以在$PATH

中找到

除非赋值另有说明,否则忽略变量和控制流。只需提供一个查看$PATH的{​​{3}}并执行用户输入的任何内容(可能是通过posix_spawn())并传递命令行参数。

答案 5 :(得分:0)

Lowball回答:

如果程序非常简单,那么可以使用命令“system("putdesiredcommandhere");”执行类似脚本的简单系统调用

在程序中安装“printf”时,在stdio.h的帮助下进行简单的系统调用。

小代码示例如下。

#include <stdio.h>
#include <stdlib.h>
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脚本转录为c程序。它需要对脚本中的每一行使用系统调用。