Shell 在 C 中 - 如何读取和执行用户输入?

Shell in C - how to read and execute user input?

我的任务是用 C 写一个非常简单的 shell。我没有很多资源,我刚开始学习 C,我只用过 scanf()printf() 和编码的简单函数。我只知道它应该写成fork()和不同的exec()。我花了很多时间分析其他shell,但我不明白程序的结构和一些功能,例如:

  1. 解析,为什么要解析?如果我知道我不会在命令中使用参数,我只想将输入与我自己的函数(如 help()date() 进行比较并执行它们。
  2. 正在读取用户输入。使用 fgets() 然后 strcmp()?
  3. 正在执行,它是如何工作的? execvp() 如何知道用户输入是我的 main 中的命令(函数)或程序文件夹中的程序?

首先,让我说这对于刚学习 C 的人来说听起来像是一项艰巨的任务,除非非常小心地限制它。您需要分析其他 shell 是没有意义的。我建议您与助教谈谈作业的范围,以及根据您的经验您应该做什么。

不过要回答你的问题:

why do we need parsing?

解析是(在此上下文中)获取一系列字符并生成您的程序可以处理的数据结构。现在,如果不应该有任何参数、每行没有多个命令等,这可能是一个相当简单的结构。但是,您至少必须确保用户确实有没有使用参数,没有写下无效的命令行,关闭了他们的左括号等等。

If I know I won't use arguments in commands

该程序不是为您可以预测其行为的完美用户编写的。您必须适应任何可能插入任何内容的用户;你需要注意这种情况并报告错误。

reading user input. Using the fgets() and then strcmp()?

请记住,fgets() 可能无法通过整行 - 如果该行比您的缓冲区长度减去 1 长。但也许您是 gua运行 遇到了行长度限制?或者允许在过长的行上失败?

此外,可能允许用户使用额外的白色-space作为行的一部分,在这种情况下strcmp()可能不会给你想要的。

executing, how does it works? How execvp() knows that the user input is a command(function) in my main or program in my program folder?

查看 execvp()(和朋友)的 man page。基本上,当您调用 execvp() 时发生的是指定位置的二进制文件获得 运行,其命令行是您作为 execvp() 的第二个参数传递的内容。假设你运行

execvp("/path/to/foo", "/path/to/foo", "bar");

所以,/path/to/foo 处的程序是 运行。像任何程序一样,它的 argv[0] 是它自身的路径。它的 argc 将是 2,它的 argv[1] 将是 "bar"。它的工作目录(以及用户和组 ID)将是 运行 execvp() 进程的当前目录、用户和组 ID,所以 - 不一定是 /path/to/foo.

继续前面的例子,你可以这样做:

chdir("/path/to");
execvp("foo", "foo", "bar");

那时 foo 会 运行 而 argv[0]foo