这是我的操作系统课程作业说明的摘录。粗体部分是我无法理解的部分,我现在也无法联系到教授,我真的很想今晚开始。我知道环境变量是什么,我想...只是在shell中声明的变量,对吧?但粗线特别是什么意思?
编写C程序以实现用户执行命令的交互式shell。
调用这个程序myshell(所以使用gcc -o myshell -Wall等来 编译)。
创建一个无限循环,重复提示用户输入 命令(参见下面的示例输出和输入)。
在执行用户输入的命令之前,必须执行命令 使用环境变量THEPATH指定的路径找到(不要 使用PATH!)。默认情况下,未设置THEPATH变量,因此 测试时,您需要手动设置(并取消设置)此变量(请参阅 详情如下)。如果找到THEPATH,您的程序必须执行 通过fork()和一个exec()系统在子进程中命令 调用
要获取并解析THEPATH,请考虑使用getenv()函数和 strtok()或strsep()函数。
答案 0 :(得分:1)
对于运行程序的shell,它必须知道程序的位置。例如,您希望能够在提示符下键入ls
,但可能会在ls
找到/bin/ls
的实际二进制文件。这就是PATH
(或您的情况,THEPATH
)的来源。当您键入ls
时,shell会关闭并在每个PATH
目录中查找匹配的程序名称。当它找到一个时,就会运行它。我们以ls
为例,PATH
设置为:
/usr/local/bin:/usr/bin:/bin
假设ls
为/bin/ls
,那么shell首先在ls
中查找/usr/local/bin
,找不到它,然后查看/usr/bin
,然后终于在/bin
中找到并执行它。
实际上正在执行此操作是您的作业中有关getenv
,strtok
和strsep
的提示的来源。
答案 1 :(得分:0)
您的变量THEPATH
应包含目录列表,以冒号分隔,如
THEPATH=/usr/bin:/bin:some-other-dirs
您必须将其解析为目录列表。当用户输入命令时,您必须扫描所有目录,以便查找名称与用户输入的命令相匹配的可执行文件。
在这种复杂程度上编写shell并不是一项初学任务,如果你不理解系统的PATH处理是如何工作的(你只是在模仿shell的作用),那么你可能会在你的头脑中。 / p>
答案 2 :(得分:0)
我知道我已经迟到了,但你可以在这里耍弄狡猾的伎俩,这就是傅师傅的精神“通过不编码获得优点”。 execlp()
,execvp()
和execvpe()
C库函数实际上为您搜索PATH变量。您所要做的就是用环境中的THEPATH替换PATH。它使您的shell更安全,因为您的所有子进程都将使用原始的THEPATH作为路径。
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()
和":"
作为分隔符。
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 */
}