基本的C Shell实现:执行命令
我被困在一项工作中,这项工作要求我用C编写一个在minix上运行的基本shell,遵循下面(1)的伪代码。这是我第一次使用C,现在我有点不知所措。我几乎成功地编写了程序的第一部分(提示用户输入,然后将输入解析为令牌,分解为命令和参数)。但我正在努力执行命令 我不是在寻找一个只为我做工作然后给我答案的人,我真正需要的是帮助我理解我需要做什么来完成任务(例如,一个总体大纲,我可以使用的资源等) 任何帮助都将不胜感激 *以下是关于这个问题过于宽泛的建议,我想指出,我在这里遇到的主要问题是理解“execve”函数(即使在阅读手册页之后)基本的C Shell实现:执行命令,c,shell,C,Shell,我被困在一项工作中,这项工作要求我用C编写一个在minix上运行的基本shell,遵循下面(1)的伪代码。这是我第一次使用C,现在我有点不知所措。我几乎成功地编写了程序的第一部分(提示用户输入,然后将输入解析为令牌,分解为命令和参数)。但我正在努力执行命令 我不是在寻找一个只为我做工作然后给我答案的人,我真正需要的是帮助我理解我需要做什么来完成任务(例如,一个总体大纲,我可以使用的资源等) 任何帮助都将不胜感激 *以下是关于这个问题过于宽泛的建议,我想指出,我在这里遇到的主要问题是理解“exec
(一)
正如您的问题下面的评论中提到的,如果这是您第一次使用C,您应该学习如何编写基本的Hello World程序,而不是如何从头开始编写unix shell 但既然您提出了这个问题,我将用您已有的代码片段为您提供一些指导:-)
- 首先,对
和fork()
进行盲调用,甚至不检查输入是否是有效的unix命令,这是非常糟糕的做法execve()
- 您需要首先检查输入是否是可以实际执行的命令。为此,必须定位(如果存在)输入命令的二进制文件。例如,ls命令实际上是位于/bin/ls中的二进制文件。对于Unix用户来说,幸运的是,存储在环境中的名为PATH的变量将通知shell在何处查找二进制文件
将打印存储在环境中的所有变量。通过执行此操作,您将看到一行内容,根据每个操作系统的不同,大致如下所示:$>env
- 因此,如果要执行的命令存在,它的二进制文件应该位于其中一个文件夹中
- 作为main函数的第三个参数,您可以在C程序中检索
。迭代它,直到找到路径行char**env
- 将此行拆分为路径列表
- 迭代此列表,并在每个路径的末尾附加输入命令。然后,将其传递给非常方便的
函数,该函数将为您提供一些有用的信息(如果文件存在,如果它具有执行权限…)。顺便说一句,阅读《男人2》统计数据对你的锻炼也有很大帮助stat()
- 在迭代过程中,如果创建的路径中有一条存在并具有执行权限,请保存此路径,然后使用
执行它。否则,如果创建的路径都不存在(execve()
returning-1)或没有执行权限,则输入可能不是命令。您还应该了解内置的stat()
$>用于定位现有命令或别名
fork()
和execve()
的教程
祝你好运 正如您的问题下面的评论中提到的,如果这是您第一次使用C,您应该学习如何编写基本的Hello World程序,而不是如何从头开始编写unix shell 但既然您提出了这个问题,我将用您已有的代码片段为您提供一些指导:-)
- 首先,对
和fork()
进行盲调用,甚至不检查输入是否是有效的unix命令,这是非常糟糕的做法execve()
- 您需要首先检查输入是否是可以实际执行的命令。为此,必须定位(如果存在)输入命令的二进制文件。例如,ls命令实际上是位于/bin/ls中的二进制文件。对于Unix用户来说,幸运的是,存储在环境中的名为PATH的变量将通知shell在何处查找二进制文件
将打印存储在环境中的所有变量。通过执行此操作,您将看到一行内容,根据每个操作系统的不同,大致如下所示:$>env
- 因此,如果要执行的命令存在,它的二进制文件应该位于其中一个文件夹中
- 作为main函数的第三个参数,您可以在C程序中检索
。迭代它,直到找到路径行char**env
- 将此行拆分为路径列表
- 迭代此列表,并在每个路径的末尾附加输入命令。然后,将其传递给非常方便的
函数,该函数将为您提供一些有用的信息(如果文件存在,如果它具有执行权限…)。顺便说一句,阅读《男人2》统计数据对你的锻炼也有很大帮助stat()
- 在迭代过程中,如果创建的路径中有一条存在并具有执行权限,请保存此路径,然后使用
执行它。否则,如果没有execve()
#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 */ } } }