0

这是我的操作系统课作业说明的摘录。粗体部分是我无法理解的部分,我现在也无法联系到教授,我真的很想今晚开始。我知道环境变量是什么,我想......只是在 shell 中声明的一个变量,对吧?但是,粗体线的具体含义是什么?

编写一个 C 程序来实现一个交互式 shell,用户可以在其中执行命令。

调用这个程序 myshell (所以使用 gcc -o myshell -Wall 等来编译)。

创建一个重复提示用户输入命令的无限循环(参见下面的示例输出和输入)。

在执行用户输入的命令之前,必须使用环境变量 THEPATH 指定的路径找到该命令(不要使用 PATH!)。默认情况下,未设置 THEPATH 变量,因此为了进行测试,您需要手动设置(和取消设置)此变量(请参阅下面的详细信息)。如果找到 THEPATH,您的程序必须通过 fork() 和其中一个 exec() 系统调用在子进程中执行该命令。

要获取和解析 THEPATH,请考虑使用 getenv() 函数和 strtok() 或 strsep() 函数。

4

3 回答 3

1

对于运行程序的 shell,它必须知道该程序在哪里。例如,您希望能够ls在提示符处键入,但实际的二进制文件ls可能位于/bin/ls. 这就是PATH(或您的情况THEPATH)出现的地方。当您键入ls时,shell 会关闭并在每个PATH目录中查找具有匹配名称的程序。当它找到一个时,它会运行它。让我们ls用作示例,并PATH设置为:

/usr/local/bin:/usr/bin:/bin

假设ls/bin/ls,那么shell首先查找lsin /usr/local/bin,没有找到,然后查找 in /usr/bin,最后找到/bin并执行。

实际上,执行此操作是您的作业中关于getenvstrtok和的提示的strsep来源。

于 2012-09-30T03:04:35.160 回答
0

您的变量THEPATH应该包含一个目录列表,用冒号分隔,如

THEPATH=/usr/bin:/bin:some-other-dirs

您必须将其解析为目录列表。当用户输入命令时,您必须扫描所有目录才能找到名称与用户输入的命令匹配的可执行文件。

以这种复杂程度编写 shell 不是初学者的任务,如果您不了解系统的 PATH 处理是如何工作的(您只是在模拟 shell 的作用),您可能会不知所措。

于 2012-09-30T03:04:01.410 回答
0

我知道我迟到了,但是您可以本着 Foo 大师的“不编码获得优势”的精神在这里玩一个肮脏的把戏。和C 库函数实际上为您搜索 PATHexeclp()变量execvp()execvpe()您所要做的就是在环境中将 PATH 替换为您的 THEPATH。它也使你的 shell 更安全,因为你所有的子进程都将使用你原来的 THEPATH 作为 PATH。

int i_path = -1;
int i_thepath = -1;
int i = 0;
while (envp[i] != NULL) {
    if (strstr(envp[i], "PATH=") == envp[i])
        i_path = i;
    if (strstr(envp[i], "THEPATH=") == envp[i])
        i_thepath = i;
    i++;
}
if (i_path >= 0 && i_thepath >= 0)
    envp[i_path] = envp[i_thepath] + 3; /* discard 'THE' */
else if (i_thepath >= 0)
    envp[i_thepath] = envp[i_thepath] + 3; /* discard 'THE' */
execvpe(command, argv, envp);

如果您手动解析 THEPATH,请不要创建目录列表。在像 Perl 这样的高级语言中这很容易,但在 C 中涉及手动动态内存分配,因为您事先不知道 THEPATH 中有多少 dir 元素。要进行内存分配,您需要先遍历字符串。但是你可以在第一次迭代中完成真正的工作,使用strtok()with":"作为分隔符。

char *thepath = envp[i_thepath];
char *dir;
strtok(thepath, "="); /* first discard 'THEPATH=' */
while (dir = strtok(NULL, ":") {
    /* now check if dir+command exists and is execuatble, exec */
}
于 2013-09-04T06:45:26.837 回答