我被困在一项工作中,需要我按照下面的伪代码 (1) 用 C 编写一个基本的 shell 以在 minix 上运行。这是我第一次使用 C,当时我有点不知所措。我刚刚设法编写了程序的第一部分(提示用户输入,然后将输入解析为标记以分解为命令和参数)。但是我正在努力执行命令。
我不是在找人帮我完成工作然后给我答案,我真正需要的是帮助我理解完成任务需要做什么(即总体大纲,我可以使用的资源等)
任何帮助将不胜感激!
*根据问题过于宽泛的建议,我想指出我在这里遇到的主要问题是理解“execve”函数(即使在阅读手册页之后)
(1)
#define TRUE 1
/* declare cmd, params, envp, stat, prompt, readcmd */
while (TRUE) { /* repeat forever */
prompt(); /* display prompt */
readcmd(cmd, params); /* read input from terminal*/
if (fork() != 0) { /* fork child process */
/* parent code */
waitpid(-1, &stat, 0); /* wait for child */
} else {
/* child code */
execve(cmd, params, envp); /* execute command */
}
}
}
最佳答案
如您问题下方的评论所述,如果这是您第一次使用 C,您应该学习如何编写基本的Hello World 程序而不是如何从头开始编写 unix shell!
但既然你问了,我将用你已有的代码片段给你一些指导方针:-)
- 首先,盲目调用
fork()
是非常糟糕的做法。和execve()
甚至不检查您的输入是否是有效的 unix 命令。 - 您需要首先检查输入的命令是否是可以实际执行的命令。为此,您必须找到(如果存在)输入命令的二进制文件。例如,ls 命令实际上是位于 /bin/ls 中的二进制文件。对于 Unix 用户来说幸运的是,一个名为 PATH 并存储在环境中的变量将通知 shell 在哪里寻找二进制文件。
-
$> env
将打印存储在环境中的所有变量。通过这样做,您将看到根据每个操作系统看起来很像的一行:
PATH=/usr/lib/qt-3.3/bin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin
此行包含几个用冒号“:”连接的路径,这些路径对应于存储常见系统二进制文件的文件夹。
因此,如果您要执行的命令存在,它的二进制文件应该位于这些文件夹之一!
- 作为主函数的第三个参数,您可以检索
char **env
在你的 C 程序中。遍历它直到找到 PATH 行。 - 将这一行拆分为路径列表
- 遍历此列表,并为每个路径在末尾附加您的输入命令。然后,将它传递给非常方便的
stat()
函数会给你一些有用的信息(如果文件存在,如果它有执行权......)。顺便说一下,阅读 man 2 stat 也会对你在这个练习中有很大帮助 - 在您的迭代中,如果创建的路径之一存在并具有执行权限,请保存此路径并稍后使用
execve()
执行它.否则,如果创建的路径都不存在(stat()
返回 -1)或没有执行权,则输入可能不是命令。您还应该了解内置函数 http://www.gnu.org/software/bash/manual/html_node/Bourne-Shell-Builtins.html#Bourne-Shell-Builtins $> which <command>
对于定位现有命令或别名非常有用
- 作为主函数的第三个参数,您可以检索
这应该可以帮助您完成整个过程,但话又说回来,我还建议您在 fork()
上做几个教程。和 execve()
.
祝你好运!
关于c - 基本 C Shell 实现 : Executing Commands,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33756849/