简体   繁体   English

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

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

My assignment is to write a very simple shell in C. I don't have many sources given and I have just started learning C, I have used only scanf() and printf() and coded simple functions. 我的任务是用C语言编写一个非常简单的shell。我给出的源代码并不多,我刚刚开始学习C语言,我只使用了scanf()printf()以及简单的编码函数。 I only know it supposed to be written with fork() and different exec() . 我只知道它应该用fork()和不同的exec()编写。 I spent a lot of time analyzing other shells, but I don't understand the structure of programs and some functions, like: 我花了很多时间分析其他外壳,但是我不了解程序的结构和某些功能,例如:

  1. parsing, why do we need parsing? 解析,为什么我们需要解析? If I know I won't use arguments in commands, I would like only to compare input with my own functions like help() or date() and execute them. 如果我知道我不会在命令中使用参数,我只想将输入与自己的函数(例如help()date()并执行它们。
  2. reading user input. 阅读用户输入。 Using the fgets() and then strcmp() ? 使用fgets()然后使用strcmp()吗?
  3. 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()如何知道用户输入是我的main文件夹还是程序文件夹中的程序中的命令(函数)?

First, let me say this sounds like a daunting task for a person just learning C, unless it's very carefully restricted. 首先,让我说,对于一个刚刚学习C的人来说,这听起来像一个艰巨的任务,除非它受到非常仔细的限制。 It does not make sense for you to need to analyze other shells. 您需要分析其他外壳没有任何意义。 I'd advise you talk to a teaching assistant about the scope of the assignment, and what you're expected to do given your experience. 我建议您与教学助理讨论作业的范围,以及根据您的经验应该做的事情。

To answer your questions, though: 不过,要回答您的问题:

why do we need parsing? 为什么我们需要解析?

Parsing is (in this context) taking a sequence of characters and producing a data structure which your proagram can work on. 解析是(在这种情况下)采用一系列字符并产生一个数据结构,程序可以对其进行处理。 Now, this could be a rather simple structure if there are not supposed to be any arguments, no multiple commands per line etc. However, you at least have to make sure that the user has indeed not used arguments, not written down an invalid command line, closed their open parentheses and so on. 现在,如果不应该有任何参数,每行没有多个命令等,这可能是一个相当简单的结构。但是,您至少必须确保用户确实没有使用过参数,没有写下无效的命令线,封闭的括号等。

If I know I won't use arguments in commands 如果我知道我不会在命令中使用参数

The program is not written for the perfect user whose behavior you can predict. 该程序不是为可以预测其行为的完美用户编写的。 You must accommodate any user, who may insert just about anything; 您必须容纳任何可以插入几乎所有内容的用户; you'll need to notice this case and report an error. 您需要注意这种情况并报告错误。

reading user input. 阅读用户输入。 Using the fgets() and then strcmp() ? 使用fgets()然后使用strcmp()吗?

Remember that fgets() may not get through the entire line - if the line is longer than your buffer length minus 1. But perhaps you are guaranteed a line length limit? 请记住, fgets()可能无法遍及整行-如果该行的长度大于缓冲区长度减1。但是也许可以保证行长度受到限制? Or are allowed to fail on overly long lines? 还是被允许在超长线路上失败?

Also, it might be the case that the user is allowed to use extra white-space as part of the line, in which case strcmp() might not give you want you want. 同样,在某些情况下,可能允许用户使用多余的空格作为行的一部分,在这种情况下, 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()如何知道用户输入是我的主文件夹还是程序文件夹中的程序中的命令(函数)?

Have a look at the man page for execvp() (and friends). 看看execvp()手册页 (和朋友)。 Basically, what happens when you call execvp() is that the binary at a specified location gets run, and its command-line is what you pass as the second argument of execvp() . 基本上,调用execvp()时发生的事情是运行指定位置的二进制文件,而其命令行是您作为execvp()的第二个参数传递的。 Suppose you run 假设您跑步

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

so, the program at /path/to/foo is run. 因此,将运行/path/to/foo的程序。 Like any program, its argv[0] is the path to itself. 像任何程序一样,其argv[0]是其自身的路径。 Its argc will be 2 and its argv[1] will be "bar" . argc将为2 ,其argv[1]将为"bar" Its working directory (and user and group id) will be the current directory, and user and group id, of the process which ran the execvp() , so - not necessarily /path/to/foo . 它的工作目录(以及用户和组ID)将是运行execvp()的进程的当前目录以及用户和组ID,因此不一定是/path/to/foo

Continuing the previous example, you could do: 继续前面的示例,您可以执行以下操作:

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

at which time foo would run with argv[0] being foo . 那时foo将以argv[0]foo

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM