c - 用 C 编写自己的 Unix shell - PATH 和 execv 的问题

标签 c shell unix execv getenv

我正在用 C 编写自己的 shell。它需要能够显示用户当前目录,根据完整路径执行命令(必须使用 execv),并允许用户使用 cd 更改目录。

这是作业。老师只给了我们 C 语言的基本入门知识和关于该程序应该如何工作的非常简短的框​​架。由于我不是一个轻易放弃的人,我已经研究了三天如何做到这一点,但现在我被难住了。

这是我目前所拥有的:

  • 显示用户的用户名、计算机名和当前目录(默认为主目录)。
  • 提示用户输入,并获取输入
  • 将用户输入的“”拆分为参数数组
  • 通过“:”将环境变量 PATH 拆分为 token 数组

我不确定如何从这里开始。我知道我必须使用 execv 命令,但在我对谷歌的研究中,我还没有真正找到我理解的例子。例如,如果命令是 bin/ls,execv 如何知道显示主目录中的所有文件/文件夹?我如何告诉系统我更改了目录?

我经常使用这个网站,这很有帮助:http://linuxgazette.net/111/ramankutty.html但我又一次被难住了。

感谢您的帮助。让我知道是否应该发布一些现有代码,但我不确定是否有必要。

最佳答案

要执行 cd 命令,您只需要系统调用 chdir

#include <unistd.h>

int chdir(
    const char *path /* the path name */
);

所以你可以这样调用:

int ret1 = chdir("../foo/bar");

chdir 的返回值为 0,当可以切换到该目录时,如果发生错误,则为 -1。对于错误,您应该合并手册页。

任何程序都可以检查当前目录,因此如果您不带任何参数执行 ls,则 ls 会检查它在哪个目录中运行并将该目录用作唯一参数。这是 ls 的特性,而不是 execv 调用的特性。

对于第二部分。

#include <unistd.h>
int execv(
     const char *path, /* programm path*/
     char *const argv[]/* argument vector*/
);

execv 在给定的 path 中执行一个可执行文件,并使用 argv 中给定的参数。 所以如果你想执行/bin/ls ../foo/bar,你需要类似于

的东西
char *cmd_str = "/bin/ls";
char *argv[] = {cmd_str, "../foo", "/bar", NULL };
if (execv(cmd_str, argv) == -1 ){
    /* an error occurred */
}

execv 返回的错误是-1。如果您想知道为什么它没有执行命令,请查看手册页。

char *argv[] = {cmd_str, "../foo", "/bar", NULL }; 中的 NULL 表示有NULL 之后没有其他参数。

第三部分。 基于 Unix 的系统通常将其中带有/的命令视为可以直接执行的命令。这意味着您首先要检查给定的命令字符串中是否有斜线。

int ret_value;
if (strchr(cmd_str, '/')
    if (execv(cmd_str, argv) == -1 ){
        /* an error occurred */
    }

如果没有斜杠,则需要遍历 PATH 中的所有目录并检查是否可以执行该命令。所以给定的命令是 ls ../foo/bar 并且假设 PATH 的值是 ".:/sbin:/bin:/usr/bin “。 然后我们会尝试首先执行 ./ls ../foo/bar 然后是 /usr/bin/ls ../foo/bar 最后是 /bin/ls ../foo/bar.

希望这对您有所帮助。

关于c - 用 C 编写自己的 Unix shell - PATH 和 execv 的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12650092/

相关文章:

linux - awk 以制表符作为分隔符

linux - 在 shell 脚本中设置目标文件夹

unix - 从 tar gzipping UNIX 中的目录中排除文件

c - 在C中显示 float 的小数位

c - 查找哪些页面不再与写时复制共享

shell - 如果shell中的大小非零,如何复制文件?

linux - 关闭 getopt_long (optarg.h) 中的缩写?

c - 在 Xcode 上编译时出现 (lldb)

调用特定宏时显示自定义错误字符串

unix - 不能使用 '>' 或 '>>' 从 log.Println() 和 log.Printf() 写入文件