C 在调用 execvp 之前测试文件是否存在

标签 c shell testing path execvp

我正在 ubuntu 上编写一个 UNIX minishell,并尝试在此时添加内置命令。当它不是内置命令时,我 fork 然后子进程执行它,但是对于内置命令,我将在当前进程中执行它。

所以,我需要一种方法来查看文件是否存在(如果存在,这不是内置命令),但是 execvp 使用环境 PATH 变量自动查找它们,所以我不知道如何手动事先检查。

那么,你们知道我如何通过提供名称来测试参数以查看它是否是内置命令吗?

谢谢你们。

最佳答案

我测试了Tom的答案

它包含了一些问题。我在这里修复了它们并提供了一个测试程序。

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/stat.h>

int is_file(const char* path) {
    struct stat buf;
    stat(path, &buf);
    return S_ISREG(buf.st_mode);
}

/*
 * returns non-zero if the file is a file in the system path, and executable
 */
int is_executable_in_path(char *name)
{
    char *path = getenv("PATH");
    char *item = NULL;
    int found  = 0;

    if (!path) 
        return 0;
    path = strdup(path);

    char real_path[4096]; // or PATH_MAX or something smarter
    for (item = strtok(path, ":"); (!found) && item; item = strtok(NULL, ":"))
    {
        sprintf(real_path, "%s/%s", item, name);
        // printf("Testing %s\n", real_path);
        if ( is_file(real_path) && !(
               access(real_path, F_OK) 
            || access(real_path, X_OK))) // check if the file exists and is executable
        {
            found = 1;
        }
    }

    free(path);
    return found;
}

int main()
{
    if (is_executable_in_path("."))
        puts(". is executable");
    if (is_executable_in_path("echo"))
        puts("echo is executable");
}

注释

  1. access 返回值的测试被反转
  2. 第二个 strtok 调用有错误的分隔符
  3. strtok 更改了 path 参数。我的示例使用副本
  4. 没有任何东西可以保证连接的 real_path 中的正确路径分隔符 char>
  5. 没有检查匹配的文件是否真的是一个文件(目录也可以是“可执行的”)。这会导致奇怪的事情,比如 . 被识别为外部二进制文件

关于C 在调用 execvp 之前测试文件是否存在,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12765010/

相关文章:

c - 识别/防止静态缓冲区溢出的工具和方法

linux - while 循环中的 Case 语句,shell 脚本

iphone - 在 iOS 上测试应用程序更新的正确方法?

testing - saltstack 测试 : render as each host in turn

c++ - 具有 C/C++ 接口(interface)的人脸检测库

c - 意外的随机数

c - 我不明白这个程序是如何工作的

PHP shell_exec()、exec() 和 system() 仅返回部分输出

bash - 哪个 Unix 命令可以从这个字符串中获取数字?

testing - 在 Spring Boot 测试期间替换 @Configuration 中的 @Value 属性