Shell 在 C 中 - 如何读取和执行用户输入?
Shell in C - how to read and execute user input?
我的任务是用 C 写一个非常简单的 shell。我没有很多资源,我刚开始学习 C,我只用过 scanf()
和 printf()
和编码的简单函数。我只知道它应该写成fork()
和不同的exec()
。我花了很多时间分析其他shell,但我不明白程序的结构和一些功能,例如:
- 解析,为什么要解析?如果我知道我不会在命令中使用参数,我只想将输入与我自己的函数(如
help()
或 date()
进行比较并执行它们。
- 正在读取用户输入。使用
fgets()
然后 strcmp()
?
- 正在执行,它是如何工作的?
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
。
我的任务是用 C 写一个非常简单的 shell。我没有很多资源,我刚开始学习 C,我只用过 scanf()
和 printf()
和编码的简单函数。我只知道它应该写成fork()
和不同的exec()
。我花了很多时间分析其他shell,但我不明白程序的结构和一些功能,例如:
- 解析,为什么要解析?如果我知道我不会在命令中使用参数,我只想将输入与我自己的函数(如
help()
或date()
进行比较并执行它们。 - 正在读取用户输入。使用
fgets()
然后strcmp()
? - 正在执行,它是如何工作的?
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 thenstrcmp()
?
请记住,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
。