c - 基本 C Shell 实现 : Executing Commands

标签 c shell

我被困在一项工作中,需要我按照下面的伪代码 (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

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

  • 因此,如果您要执行的命令存在,它的二进制文件应该位于这些文件夹之一!

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

这应该可以帮助您完成整个过程,但话又说回来,我还建议您在 fork() 上做几个教程。和 execve() .

祝你好运!

关于c - 基本 C Shell 实现 : Executing Commands,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33756849/

相关文章:

c - 用 c 编写我自己的 shell - free() 导致问题

linux - 为什么flock会从文件中删除现有文本?

c - LoRaWAN OTAA协议(protocol)规范

c - xlib半透明窗口背景

c - 浮点转换假设 : (int)(float)n == n

linux - 在 shell 脚本中结合 ssh 和 scp 命令

c - 为什么我的循环会创建额外的链表节点?

c - 如何查找 sscanf 输入程序集的格式

json - 在 shell 脚本中解码 JSON 和 base64 编码值

linux - 您可以在远程运行的 shell 脚本中提示用户输入吗?