我正在用 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/