c - 在C中查找已知名称的文件地址

标签 c shell ubuntu cd chdir

我正在为一个项目用 C/Ubuntu 编写自己的 shell,但在使用 chdir() 实现 cd 时遇到了一些困难。 chdir() 需要路径名,但由于用户将编写(假设)cd DesktopDesktop 不是路径名,因此程序将失败。

这是我的那部分代码:

child = fork();
if (child == 0) {
    if (!strcmp(args[0], "ls")) {
        execv("/bin/ls", args);
    }
    if (!strcmp(args[0] , "cd")) {
        chdir(args[1]);
    }  
    perror("Error");
    exit(1);  //Failure
} else {
    do {
       waitpid(child, &status, WUNTRACED);
} while(!WIFEXITED(status) && !WIFSIGNALED(status)); 

所以我认为问题是 args[1] 获取了诸如 "Desktop" 之类的东西而不是地址,所以 chdir 失败了。我在终端测试了它,除了 cd 之外,所有其他命令都有效。我的问题是,我怎样才能使这个 chdir 工作?换句话说,我怎样才能将 args[1] 的路径提供给 chdir

让我这样说吧。当我将 cd Desktop 写入终端时,它可以正常工作。当我将 cd Desktop 写入我自己的 shell 时,它会尝试执行 chdir("Desktop") 但失败了。

最佳答案

你使用 exec 来运行 ls 命令,我怀疑你在选择要执行的命令之前 fork() 进程:chdir(args[1])在子进程中执行,子进程改变当前目录,然后退出。每个进程都有自己的当前目录。父(shell)进程当前目录不受其子进程更改的影响,它保留其当前目录。

大多数命令应该在不 fork 的shell进程中执行,只有外部命令应该在 fork 到子进程后执行。

这是您的代码的修改版本:

/* frist execute local commands in the shell process. */
if (!strcmp(args[0], "cd")) {
    if (!args[1]) {
        fprintf(stderr, "cd: missing argument\n");
    } else
    if (chdir(args[1])) {
        perror("chdir");
    }
} else
if (!strcmp(args[0], "exit")) {
    int status = args[1] ? atoi(argv[1]) : 0;
    exit(status);
} else {
    /* otherwise, fork and attempt to execute an external command */
    child = fork();
    if (child == 0) {
        if (!strcmp(args[0], "ls")) {
            execv("/bin/ls", args);
        }
        /* if exec failed, the child process is still running */
        perror("exec");
        exit(1);  //Failure
    } else {
        do {
           waitpid(child, &status, WUNTRACED);
    } while(!WIFEXITED(status) && !WIFSIGNALED(status));
}

关于c - 在C中查找已知名称的文件地址,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35813837/

相关文章:

c - 将任意结构从 C 传递到 LUA 并访问它

linux - 如何使用sed命令更改limits.conf中的ulimit值?

mysql - 将 Ruby on Rails 连接到现有 MySQL 数据库(之前安装了 XAMPP)

android - bin/bash : -c: line 0: syntax error near unexpected token `;;'

c# - Ubuntu 19.10 上的 Unity3D,带有 vscode 和 C# 扩展 : get an error and the autocomplete doesn't working

bash - 将最终 Gnuplot 拟合参数集从终端存储到文件中

c - 编译内核模块时如何解决函数名冲突

c - 为什么C中全局变量的存储类别隐式定义为 "extern"?

c - 将 C 库链接到 R

linux - 使用 bash 脚本替换配置文件变量