【问题标题】:How to use a c program to determine if the user entered a command that exists in linux [closed]如何使用c程序确定用户是否输入了linux中存在的命令[关闭]
【发布时间】:2016-05-23 17:01:59
【问题描述】:

我正在做这个程序,让用户输入 c 字符串,然后我想创建一个函数来检查用户输入的字符串是否是 linux 命令。 前任。 用户:猫 输出:cat 是一个命令

用户:你好 输出: hello 不是命令

等等……

有人告诉我可以使用 execvp,但我不想执行命令只是为了确定它是否存在,我只想确定它是否存在。

我认为可以使用 linux 的 whereis 命令输出特定命令的位置,但我不知道如何在 c 中实现。

我还被告知 stat() 可以工作,但我不确定它是如何工作的,因为它的 marcos 只更改目录和文件。那么像 cat 文件这样的命令吗?如果是这样,当我运行 stat 时:

stat(cmd, &buff);

我不需要 cmd 的路径吗?

总的来说,我如何确定用户是否使用 c 在 linux 中输入了有效命令并让解决方案相对可移植?

【问题讨论】:

    标签: c linux shell command-line command


    【解决方案1】:

    您可以结合使用 Linux which 命令和 C 函数 popen

    char testCmd[100];
    char usrCmd[100];
    
    strcpy(testCmd, "which ");
    strcpy(usrCmd, "cat hello.txt");
    strncat(testCmd, usrCmd, 93);
    
    char path[100];
    FILE *p = popen( testCmd , "r");
    if(p ) {
        while(fgets(path, sizeof(path), p) != NULL) {
            printf("%s", path);
        }
    }
    

    which 命令返回其参数的路径,传递 cat hello.txt 似乎也可以。如果您期待诸如输出重定向之类的讨厌的事情,那么只将用户输入的第一个单词发送到which 是有意义的。

    which 打印命令的路径(如果它在路径中)或换行符(如果找不到该命令)。

    【讨论】:

    • 你在 C 题中使用过 C++...
    • @John 我会尝试改变 C 但核心思想 whichpopen 保持不变。
    • 感谢您删除 C++ 代码。顺便说一句,你是对的,只需将命令本身传递给 which--“which cat”,而不是“which cat hello.txt”
    • 感谢这真的有帮助,现在运行良好!
    【解决方案2】:

    你写:

    我不需要 cmd 的路径

    是的。对于任何没有路径的命令(cat 不是 /usr/bin/cat),您需要在伪代码中遍历 PATH 变量的所有元素:

    for (path in PATH) {
        cmdpath = concat(path, "/", cmd);
        stat(cmdpath, &statbuff);
        ...
    }
    

    但是,为了复制execvp 中的工作而费尽心思,您所做的只是为奇怪的计时(“竞赛”)错误创造了一个地方,可能会引入一个安全漏洞。有关此主题的介绍,请参阅此维基百科文章:https://en.wikipedia.org/wiki/Time_of_check_to_time_of_use

    所以解决方案通常是您不想使用的解决方案:

    if (execvp(cmd, args) == -1) {
        printf("well, that didn't go well, did it?\n");
    }
    

    想要“先看再跳”的方法是很自然的,但“试一试”的方法通常更简单、更安全。

    编辑

    您对破坏文件的担忧令人钦佩,但这正是“真实”外壳中发生的情况:

    # date >victim
    # cat victim 
    Fri Feb 12 09:23:56 CST 2016
    # shjsds >victim
    shjsds: Command not found.
    # cat victim
    #                                  ! file was clobbered
    

    【讨论】:

    • 我明白了,但我的问题主要是如果我想扩展我的代码以包含命令重定向。如果我这样做并且用户使用'>'(输出)我将不得不截断文件,然后调用 execvp 这意味着如果 execvp 失败,我会无缘无故地截断。我想阻止。
    【解决方案3】:

    stat 系统调用提供有关文件的信息,前提是您提供了文件名的完整路径。如果您想知道文件和类型以及是否是exe和Linux cmd,那么您需要从根目录搜索,然后检查每个文件,然后确定类型等。我建议您尝试了解unix如何shell 工作,那么您将了解您的问题的答案。 exec 系列系统调用执行一个程序,您需要 fork 然后在子进程中调用 exec,否则您的程序将执行新命令。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-05-26
      • 2011-03-13
      • 2023-04-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-10-24
      相关资源
      最近更新 更多