【问题标题】:C - finding full path of commandC - 查找命令的完整路径
【发布时间】:2015-02-13 16:26:28
【问题描述】:

我正在尝试查找某人在终端或控制台窗口中键入的命令的完整路径。我正在尝试使用

 getenv(PATH) 

获取命令可能存在的不同路径的':'分隔字符串,然后使用

stat() 

看它是否存在于每一个中。

由于无法使用字符串库,因此无法解析 getenv() 的返回值。

getenv(path) returns: 
PATH = /Library/Frameworks/Python.framework/Versions/3.2/bin:/Library/Frameworks/Python.framework/Versions/3.2/bin:/Library/Frameworks/Python.framework/Versions/2.7/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin

我正在尝试:

char* fullPath = getenv( "PATH" );
struct stat buffer;
int exists; 
char* fileOrDirectory = usersCommand    
exists = stat( file_or_dir, &buffer );  
if ( exists == 0 && ( S_IFDIR & buffer.st_mode ) ) {
    //dir exists
} else if ( exists == 0 && ( S_IFREG & buffer.st_mode ) ) {
    //file exists
} else {
    //neither exists
}

到目前为止,我没有使用我的 fullPath 变量。现在它只是在我的本地目录中搜索命令吗?

示例命令是 'cd' 或 'ls' 等。

如何解析 ':' 分隔的字符串,然后在每个字符串上调用 stat?除了获得有关文件或目录状态的一些信息之外,我并不完全了解缓冲区的用途,但我觉得它应该采用另一个参数,以便我可以输入我正在搜索的内容以及 fullPath。

谢谢

【问题讨论】:

  • 您可以使用strtok 解析: 分隔的字符串并检查每个文件夹中的命令。顺便说一句,cd 是内置的 shell,而不是 PATH 中的独立可执行文件。
  • 不能使用字符串库^

标签: c string parsing path


【解决方案1】:

函数strtok 是标记字符串的标准方法。有了它,您可以构建文件的完整路径名。

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

main(int argc, char **argv)
{

    char* fullPath = getenv( "PATH" );
    struct stat buffer;
    int exists;
    char* fileOrDirectory = argv[0];
    char fullfilename[1024];

    char *token = strtok(fullPath, ":");

    /* walk through other tokens */
    while( token != NULL )
    {
        sprintf(fullfilename, "%s/%s", token, fileOrDirectory);
        exists = stat( fullfilename, &buffer );
        if ( exists == 0 && ( S_IFREG & buffer.st_mode ) ) {
            printf("found file %s\n", fullfilename);
        }

        token = strtok(NULL, ":"); /* next token */
    }
    exit(0);
}

【讨论】:

    【解决方案2】:

    由于不允许使用字符串标准库函数,您需要自己编写一个字符串标记器,您可以在下面的代码行中做一些事情,您可能需要进一步改进它。

    基本上我们在这里做什么

    获取路径

    找到令牌':'

    memcpy 子字符串到 token -1

    更新路径

    重复直到'\0'。

    #define MAX_DIR_PATH_SIZE 500
    char *get_directory(char **u_path, int *done)
    {
        int i;
        char *temp  = malloc(MAX_DIR_PATH_SIZE);
        //handle error here                                                                                                                                                                                                                           
        memset(temp,0,MAX_DIR_PATH_SIZE);
        if(!u_path || !(*u_path))
            return NULL;
        int index =0 ;
    
        for(i = 0;i <= MAX_DIR_PATH_SIZE ; i++)
        {
             if(index)
                break;
             switch((*u_path)[i]) // proximity of the brackets and * is important                                                                                                                                                                   
             {
                case '\0':
                  *done  = 1;
                  index = 1;
                  memcpy(temp,*u_path,i+1);
                  printf("Last substring %s\n",temp);
                break;
                //Search for token ': ascii = 58'                                                                                                                                                                                                  
                case 0x3A:
                  index = 1;
                  memcpy(temp,*u_path,i);
                  *u_path = *u_path+i+1;
                  printf("token found : %s\n",temp);
                  break;
               default:
                 break;
            }
    
        }
        //handle error for maximum size overlimit
        return temp;
     }
    
    
    int main(int argc, char **argv)
    {
        char *fullPath = getenv( "PATH" );
        char *u_path = fullPath;
        struct stat buffer;
        int exists;
        int done = 0;
        char* fileOrDirectory = NULL;
        while(!done)
        {
            fileOrDirectory = get_directory(&u_path,&done);
            printf("new path is : %s\n",u_path);
            if(fileOrDirectory)
            {
                exists = stat( fileOrDirectory, &buffer );
                if ( exists == 0 && ( S_IFDIR & buffer.st_mode ) ) {
                    printf("directory size %lu\n",buffer.st_size);
                }
                else {
                   //do something else                                                                                                                                                                                                                
                }
                free(fileOrDirectory);
            }
        }
        return 0;
    }
    

    【讨论】:

      【解决方案3】:

      这里有一些尝试:

      // Variables needed during iteration.
      char* start = fullPath;
      char sep = ':';
      char* iter;
      char trialPath[BUFSIZ];
      
      // Get the path
      char* originalPath = getenv( "PATH" );
      
      // Make a copy of the path since we are going to modify it
      // while we are iterating on it.
      char* fullPath = malloc(strlen(originalPath) + 1);
      strcpy(fullPath, originalPath);
      
      start = fullPath;
      
      // Iterate over the path.
      for ( char* iter = start; *iter != '\0'; ++iter )
      {
         if ( *iter == sep )
         {
            *iter = '\0';
            // Now, start is a directory.
            // Check whether the user command is at this location.
            strcpy(trialPath, start);
            strcat(trialPath, "/");
            strcat(trialPath, usersCommand);
      
            // Now use stat to check whether the file exists and
            // it is an executable.
            // ....
      
      
            // If not, reset where start points to.
            start = iter + 1;
         }
      }
      
      // Deallocate memory allocated earliner.
      free(fullPath);
      

      【讨论】:

      • 在这个作业中我不能使用字符串库(im op)
      • 您可以创建strlen 的实现。叫它my_strlen。实施起来并不难。
      • 还有 strcat 和 strcpy?
      • @user93110,当。令人难以置信的是,我们如何将标准库函数视为理所当然。你的问题的答案是肯定的。它们也不太难。
      猜你喜欢
      • 1970-01-01
      • 2018-12-02
      • 1970-01-01
      • 2018-11-16
      • 1970-01-01
      • 1970-01-01
      • 2016-11-03
      • 1970-01-01
      • 2014-05-09
      相关资源
      最近更新 更多