C 如何读取和执行用户输入?

C 如何读取和执行用户输入?,c,shell,execvp,C,Shell,Execvp,我的任务是用C编写一个非常简单的shell。我没有太多的源代码,而且我刚刚开始学习C,我只使用了scanf()和printf()和编码的简单函数。我只知道它应该是用fork()和不同的exec()编写的。我花了很多时间分析其他shell,但我不了解程序的结构和一些函数,例如: 解析,为什么我们需要解析?如果我知道我不会在命令中使用参数,我只想将输入与我自己的函数(如help()或date())进行比较并执行它们 读取用户输入。使用fgets()然后使用strcmp() 执行,它是如何工作的?ex

我的任务是用C编写一个非常简单的shell。我没有太多的源代码,而且我刚刚开始学习C,我只使用了
scanf()
printf()
和编码的简单函数。我只知道它应该是用
fork()
和不同的
exec()
编写的。我花了很多时间分析其他shell,但我不了解程序的结构和一些函数,例如:

  • 解析,为什么我们需要解析?如果我知道我不会在命令中使用参数,我只想将输入与我自己的函数(如
    help()
    date()
    )进行比较并执行它们
  • 读取用户输入。使用
    fgets()
    然后使用
    strcmp()
  • 执行,它是如何工作的?
    execvp()
    如何知道用户输入是我的
    main
    中的命令(函数)或我的程序文件夹中的程序

  • 首先,让我说,对于一个刚刚学习C的人来说,这听起来像是一项艰巨的任务,除非它受到非常仔细的限制。您不需要分析其他壳。我建议你与助教谈谈作业的范围,以及根据你的经验你应该做什么

    不过,要回答您的问题:

    为什么我们需要解析

    解析是(在此上下文中)获取一系列字符并生成proagram可以处理的数据结构。现在,如果没有任何参数,每行没有多个命令等,那么这可能是一个相当简单的结构。但是,您至少必须确保用户确实没有使用参数,没有写下无效的命令行,没有关闭开括号等等

    如果我知道我不会在命令中使用参数

    该程序不是为你可以预测其行为的完美用户编写的。您必须适应任何用户,他们可以插入任何内容;您需要注意此情况并报告错误

    读取用户输入。使用
    fgets()
    然后使用
    strcmp()

    请记住,
    fgets()
    可能无法通过整行-如果该行长于缓冲区长度减去1。但也许你保证有一个行长度限制?还是允许在过长的线路上失败

    此外,可能允许用户使用额外的空白作为行的一部分,在这种情况下,
    strcmp()
    可能不会提供您想要的内容

    执行,它是如何工作的?execvp()如何知道用户输入是我的主程序中的命令(函数)还是我的程序文件夹中的程序

    查看for
    execvp()
    (和朋友)的。基本上,当您调用
    execvp()
    时,发生的情况是指定位置的二进制文件运行,其命令行是作为
    execvp()
    的第二个参数传递的。假设你跑

    execvp("/path/to/foo", "/path/to/foo", "bar");
    
    因此,运行
    /path/to/foo
    处的程序。与任何程序一样,它的
    argv[0]
    是指向自身的路径。它的
    argc
    将是
    2
    ,它的
    argv[1]
    将是
    “bar”
    。其工作目录(以及用户和组id)将是运行
    execvp()
    的进程的当前目录以及用户和组id,因此-不一定是
    /path/to/foo

    继续上一个示例,您可以执行以下操作:

    chdir("/path/to");
    execvp("foo", "foo", "bar");
    

    此时,
    foo
    将运行
    argv[0]
    being
    foo

    将其分解为更小的部分,并逐个学习每个小部分。例如,
    fork
    做什么?它的回报是什么?它是如何工作的?什么是父进程和子进程?尝试使用
    fork
    和进程,直到了解它的工作原理。然后,当您了解了
    fork
    之后,继续下一部分。等等在你了解它之前,你会对每个小部分有足够的了解,它会变成一个简单的拼图,你所要做的就是把这些小部分拼在一起。关于这个主题,exec接受一系列参数。解析是将命令字符串转换为该列表的过程。建议:避免使用scanf。您将花费大量时间调试格式字符串的神秘问题,而没有学到任何有用的东西。使用
    fread
    fgetc
    函数系列进行输入。学习使用这些工具将更加有用。