在c中实现cd命令

Implement cd command in c

如何在支持~, .., -
的c中实现cd命令 我写了下面的代码:

void exec_cd(char* command) {
    if (chdir(command) != 0) {
        perror("chdir failed");
    }
    if (!strcmp(command, "~")) {
        chdir(getenv("HOME"));
    }
    if (!strcmp(command, "/")) {
        // do stuff
    }
    if (!strcmp(command, "-")) {
        // do stuff
    }
    if (!strcmp(directory, "..")) {
        chdir("..");
    }
}  

我们如何实现~ and -并且..命令是正确的?

chdir 将更改程序的当前目录,可能是您尝试执行的命令 shell。

/..subdir等绝对和相对路径没有问题,可以直接传递给chdir系统调用。

-cd命令的一个特殊参数:cd -表示回到上一个当前目录。要实现此功能,您需要跟踪 cd 更改到的最后一个目录。在调用 chdir 之前使用 getcwd() 函数,如果成功,将之前的目录保存在全局数组中。

~ 是另一个特殊的东西:它应该在分派到命令处理程序之前扩展到主目录(HOME 环境变量的值),因此可以键入 cd ~,或者只是 cd 更改到主目录,但 cd "~" 更改到名为 "~" 的目录。 ~ 应扩展为 $(HOME),作为独立字符串或作为路径的初始部分:~/bin。请注意 ~name 应该扩展到用户 name.

的主目录

这是一个部分和简单的版本:

#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

char lastdir[MAX_PATH];  // initialized to zero

int exec_cd(char *arg) {
    char curdir[MAX_PATH];
    char path[MAX_PATH];

    if (getcwd(curdir, sizeof curdir)) {
        /* current directory might be unreachable: not an error */
        *curdir = '[=10=]';
    }
    if (arg == NULL) {
        arg = getenv("HOME");
    }
    if (!strcmp(arg, "-")) {
        if (*lastdir == '[=10=]') {
            fprintf(stderr, "no previous directory\n");
            return 1;
        }
        arg = lastdir;
    } else {
        /* this should be done on all words during the parse phase */
        if (*arg == '~') {
            if (arg[1] == '/' || arg[1] == '[=10=]') {
                snprintf(path, sizeof path, "%s%s", getenv("HOME"), arg + 1);
                arg = path;
            } else {
                /* ~name should expand to the home directory of user with login `name` 
                   this can be implemented with getpwent() */
                fprintf(stderr, "syntax not supported: %s\n", arg);
                return 1;
            }
        }
    }
    if (chdir(arg)) {
        fprintf(stderr, "chdir: %s: %s\n", strerror(errno), path);
        return 1;
    }
    strcpy(lastdir, curdir);
    return 0;
}