【问题标题】:Shell in C - how to read and execute user input?C中的Shell - 如何读取和执行用户输入?
【发布时间】:2019-05-31 19:55:00
【问题描述】:

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

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

【问题讨论】:

  • 把它分解成更小的部分,并一个一个地学习每个小部分。例如,fork 做什么?它返回什么?它是如何工作的?什么是父进程和子进程?试验fork 和进程,直到你了解它的工作原理。然后,当您了解fork 时,请继续下一部分。等等。在你知道它之前,你将对每个小部分有足够的了解,它变成一个简单的谜题,你所要做的就是把各个部分放在一起。和here's some very related reading 关于那个主题。
  • exec 接受参数列表。解析是将您的命令字符串转换为该列表的原因。
  • 建议:避免scanf。您将花费大量时间调试格式字符串的神秘问题,而不会学到任何有用的东西。使用freadfgetc 系列函数作为您的输入。学习使用这些会更有用。

标签: c shell execvp


【解决方案1】:

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

不过,要回答您的问题:

为什么我们需要解析?

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

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

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

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

请记住,fgets() 可能无法通过整行 - 如果该行比您的缓冲区长度减去 1 长。但也许您可以保证行长度限制?还是允许在过长的行中失败?

另外,可能允许用户在行中使用额外的空格,在这种情况下,strcmp() 可能无法满足您的需求。

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

查看man pageexecvp()(和朋友)。基本上,当您调用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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-10-29
    • 1970-01-01
    • 2021-08-01
    • 2016-06-05
    • 1970-01-01
    • 1970-01-01
    • 2020-04-05
    • 2011-04-30
    相关资源
    最近更新 更多