Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/cassandra/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
基本的C Shell实现:执行命令_C_Shell - Fatal编程技术网

基本的C Shell实现:执行命令

基本的C Shell实现:执行命令,c,shell,C,Shell,我被困在一项工作中,这项工作要求我用C编写一个在minix上运行的基本shell,遵循下面(1)的伪代码。这是我第一次使用C,现在我有点不知所措。我几乎成功地编写了程序的第一部分(提示用户输入,然后将输入解析为令牌,分解为命令和参数)。但我正在努力执行命令 我不是在寻找一个只为我做工作然后给我答案的人,我真正需要的是帮助我理解我需要做什么来完成任务(例如,一个总体大纲,我可以使用的资源等) 任何帮助都将不胜感激 *以下是关于这个问题过于宽泛的建议,我想指出,我在这里遇到的主要问题是理解“exec

我被困在一项工作中,这项工作要求我用C编写一个在minix上运行的基本shell,遵循下面(1)的伪代码。这是我第一次使用C,现在我有点不知所措。我几乎成功地编写了程序的第一部分(提示用户输入,然后将输入解析为令牌,分解为命令和参数)。但我正在努力执行命令

我不是在寻找一个只为我做工作然后给我答案的人,我真正需要的是帮助我理解我需要做什么来完成任务(例如,一个总体大纲,我可以使用的资源等)

任何帮助都将不胜感激

*以下是关于这个问题过于宽泛的建议,我想指出,我在这里遇到的主要问题是理解“execve”函数(即使在阅读手册页之后)


(一)


正如您的问题下面的评论中提到的,如果这是您第一次使用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

此行包含多个路径,这些路径与存储公共系统二进制文件的文件夹相对应

  • 因此,如果要执行的命令存在,它的二进制文件应该位于其中一个文件夹中

  • 作为main函数的第三个参数,您可以在C程序中检索
    char**env
    。迭代它,直到找到路径
  • 将此行拆分为路径列表
  • 迭代此列表,并在每个路径的末尾附加输入命令。然后,将其传递给非常方便的
    stat()
    函数,该函数将为您提供一些有用的信息(如果文件存在,如果它具有执行权限…)。顺便说一句,阅读《男人2》统计数据对你的锻炼也有很大帮助
  • 在迭代过程中,如果创建的路径中有一条存在并具有执行权限,请保存此路径,然后使用
    execve()
    执行它。否则,如果创建的路径都不存在(
    stat()
    returning-1)或没有执行权限,则输入可能不是命令。您还应该了解内置的
  • $>用于定位现有命令或别名
这将有助于您完成整个过程,但我也建议您做一些关于
fork()
execve()
的教程


祝你好运

正如您的问题下面的评论中提到的,如果这是您第一次使用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

此行包含多个路径,这些路径与存储公共系统二进制文件的文件夹相对应

  • 因此,如果要执行的命令存在,它的二进制文件应该位于其中一个文件夹中

  • 作为main函数的第三个参数,您可以在C程序中检索
    char**env
    。迭代它,直到找到路径
  • 将此行拆分为路径列表
  • 迭代此列表,并在每个路径的末尾附加输入命令。然后,将其传递给非常方便的
    stat()
    函数,该函数将为您提供一些有用的信息(如果文件存在,如果它具有执行权限…)。顺便说一句,阅读《男人2》统计数据对你的锻炼也有很大帮助
  • 在迭代过程中,如果创建的路径中有一条存在并具有执行权限,请保存此路径,然后使用
    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 */ 
            } 
        } 
    }