[英]What does it mean to “find a command in a path”?
这是我的作业课上我的操作系统课的摘录。 粗体部分是我无法理解的部分,我现在也无法联系到教授,我真的很想今晚开始。 我想我知道什么是环境变量...只是在shell中声明的变量,对吧? 但是,粗线特别意味着什么?
编写一个C程序来实现一个交互式外壳,用户可以在其中执行命令。
将此程序称为myshell(因此请使用gcc -o myshell -Wall等进行编译)。
创建一个无限循环,该循环反复提示用户输入命令(请参见下面的示例输出和输入)。
在执行用户输入的命令之前,必须使用环境变量THEPATH指定的路径找到该命令(不要使用PATH!)。 默认情况下,THEPATH变量未设置,因此,为了进行测试,您需要手动设置(和取消设置)此变量(请参见下面的详细信息)。 如果找到了THEPATH,则您的程序必须通过fork()和exec()系统调用之一在子进程中执行命令。
要获取和解析THEPATH,请考虑使用getenv()函数和strtok()或strsep()函数。
要让外壳程序运行程序,它必须知道该程序在哪里。 例如,您希望能够在提示符下键入ls
,但是ls
的实际二进制文件可能位于/bin/ls
。 这就是PATH
(或您的情况, THEPATH
)的输入。当您输入ls
,shell将关闭并在每个PATH
目录中查找具有匹配名称的程序。 当找到一个时,它将运行它。 让我们以ls
为例,并将PATH
设置为:
/usr/local/bin:/usr/bin:/bin
假设ls
是/bin/ls
,那么外壳程序首先在/usr/local/bin
查找ls
,没有找到它,然后在/usr/bin
查找,最后在/bin
找到并执行它。
实际上, 执行此操作是您的分配中有关getenv
, strtok
和strsep
的提示的地方。
您的变量THEPATH
应该包含目录列表,以冒号分隔,如
THEPATH=/usr/bin:/bin:some-other-dirs
您必须将其解析为目录列表。 用户输入命令时,必须扫描所有目录,以查找名称与用户输入的命令匹配的可执行文件。
以这种复杂程度编写外壳程序不是一个初学者的任务,如果您不了解系统的PATH处理如何工作(您只是在模仿外壳程序的功能),那么您可能会头疼。
我知道我来晚了,但是您可以本着Foo大师的“不编码就可取功”的精神在这里打个dirty头。 execlp()
, execvp()
和execvpe()
C库函数实际上为您搜索PATH变量。 您要做的就是在环境中用THEPATH替换PATH。 它也使您的外壳更安全,因为所有子进程都将使用原始的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()
以":"
作为分隔符strtok()
在第一次迭代中完成实际工作。
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 */
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.