基本的C外壳实现:执行命令



我被一项工作卡住了,这项工作要求我用C编写一个基本的shell,以便在minix上运行,遵循下面的伪代码(1)。这是我第一次使用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/lsATH并存储在环境中的变量将通知shell在哪里查找二进制文件
  • $> env将打印存储在环境中的所有变量。通过这样做,您将看到一条线,根据每个操作系统的不同,它看起来几乎是这样的:

PATH=/usr/lib/qt-3.3/bin:/usr/local/sbin:/usr\local/bin:/sbin:/bin:/usr/sbin:/root/bin

此行包含几个用冒号":"连接的路径。这些路径对应于存储通用系统二进制文件的文件夹。

  • 所以,如果你想执行的命令存在,它的二进制文件应该位于其中一个文件夹中!

    1. 作为主函数的第三个参数,您可以在C程序中检索char **env。遍历它,直到找到PATH
    2. 将此行拆分为路径列表
    3. 在这个列表上迭代,对于每个路径,在末尾附加您的输入命令。然后,将其传递给非常方便的stat()函数,该函数将为您提供一些有用的信息(如果文件存在,如果它有执行权限…)
    4. 在迭代过程中,如果创建的路径之一存在并具有执行权限,请保存此路径,稍后使用execve()执行。否则,如果创建的路径都不存在(stat()返回-1)或没有执行权限,则输入可能不是命令。你还应该学习内置http://www.gnu.org/software/bash/manual/html_node/Bourne-Shell-Builtins.html#Bourne-壳牌建筑
    5. $> which <command>对于查找现有命令或别名非常有用

这应该会帮助您完成整个过程,但我也建议您做几个关于fork()execve()的教程。

祝你好运!

最新更新