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

时间:2019-01-05 13:38:28

标签: c shell execvp

我的任务是用C语言编写一个非常简单的shell。我没有给出太多的源代码,而且我才刚刚开始学习C语言,我只使用了scanf()printf()并编写了简单函数。我只知道应该用fork()和不同的exec()编写。我花了很多时间分析其他外壳,但我不了解程序的结构和某些功能,例如:

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

1 个答案:

答案 0 :(得分:2)

首先,让我说,对于一个刚学习C的人来说,这听起来像是一项艰巨的任务,除非它受到非常严格的限制。您需要分析其他外壳没有任何意义。我建议您与助教讨论作业的范围,以及根据您的经验应该做的事情。

不过,要回答您的问题:

  

为什么我们需要解析?

(在这种情况下)解析是采用一个字符序列并产生一个数据结构,程序可以对其进行处理。现在,如果不应该有任何参数,每行没有多个命令等,这可能是一个相当简单的结构。但是,您至少必须确保用户确实没有使用过参数,而不是写下无效的命令行,并关闭其右括号,等等。

  

如果我知道我不会在命令中使用参数

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

  

读取用户输入。使用fgets(),然后使用strcmp()

请记住,fgets()可能无法遍及整行-如果该行的长度大于缓冲区长度减去1。但是,也许可以保证行长度限制吗?还是被允许在超长线路上失败?

此外,在某些情况下,可能允许用户使用多余的空白作为行的一部分,在这种情况下,strcmp()可能不会给您想要的内容。

  

执行,它如何工作? execvp()如何知道用户输入是我的主程序还是程序文件夹中的程序中的命令(函数)?

看看execvp()的{​​{3}}(和朋友)。基本上,调用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运行。