我编写一个shell。这是处理重定向的一小部分。我只包含导致错误的代码段。程序的这一部分应该采用命令/参数行并相应地执行该行。 wc<垃圾> junk2是一个命令行输入的例子,由于某种原因,当我执行该行时,它产生了错误垃圾:>:open:没有这样的文件或目录。程序的其余部分运行良好,但它在这里打破。
:wc<垃圾> junk2
junk: >: open: No such file or directory
1 4 31 junk2
1 4 31 total
我简单地说它按预期工作但由于某种原因我必须丢失一块拼图,因为它再次被打破了。
我看过我的数组值,它们和预期的一样。为了澄清一点,我使用了arguments数组的副本,因此通过将参数copy值设置为NULL来保持原始值不变。我将参数复制值设置为null,因此循环不会重复使用重定向。
如果您有任何建议或看到我显然无法解决的问题,我们将不胜感激。
while (arguments[i] != NULL)
{
if ((strcmp(argumentsCopy[i], "<") == 0))
{
if ((access(argumentsCopy[i + 1], R_OK) == -1))
{
printf("Cannot open %s for input\n", argumentsCopy[i + 1]);
fflush(stdout);
redirect = 1;
}
else
{
int fd = open(argumentsCopy[i + 1], O_RDONLY);
dup2(fd, STDIN_FILENO);
close(fd);
argumentsCopy[i] = NULL;
redirect = 1;
execvp(command, &arguments[i + 1]);
}
}
if ((strcmp(argumentsCopy[i], ">") == 0))
{
int fd = open(argumentsCopy[ i + 1], O_RDWR);
dup2(fd, STDOUT_FILENO);
close(fd);
argumentsCopy[i] = NULL;
redirect = 1; // avoid repeat use of redirection symbol in arguments array
execvp(command, &arguments[i + 1]);
}
i++;
}
if (redirect == 0)
{
execvp(command, execArgs); //execArgs is entire command w/ arguments
}
exit 0; //default if error occurred.
答案 0 :(得分:1)
首先,请注意您未正确使用execvp
功能。一旦对execvp
(或exec
系列中的任何调用)的调用成功,当前程序的执行将终止,并由您exec
的程序替换。因此,除非该呼叫失败,否则控制流不应该经过execvp
呼叫。因此,在确定execvp
和stdin
文件描述符都已正确重定向(如果您同时具有输入和输出重定向)之前,无法调用stdout
。从您的代码示例中,一旦检测到任何一个,您就会调用execvp
,这意味着您的shell只能重定向输入或输出,而不是两者。
但是,这不是您收到的错误的来源。考虑输入wc < junk > junk2
。根据您提供的信息,命令和参数数组将按如下方式填充:
command = "wc"
arguments[0] = ">"
arguments[1] = "junk"
arguments[2] = "<"
arguments[3] = "junk2"
arguments[4] = NULL
当i = 0
时,将采用第一个if语句,打开文件描述符并使用参数execvp
和command
执行&arguments[i+1]
。这些对应于要执行的文件和分别传递给该函数的main方法的argv
数组。在这种情况下,命令为wc
,args为{ "junk", "<", "junk2", NULL }
(因为这是从&arguments[i+1]
开始的空终止数组的值)。在Unix系统上,第一个参数(argv[0]
)通常是当前程序的名称。因此,实际的命令行参数从argv[1]
开始(有关文档,请参阅Program Arguments)。从wc
的角度来看,它应该处理的命令行参数是{ "<", "junk2", NULL }
,它处理了它认为的程序名称argv[0]
或junk
wc
将其处理的文件列表作为参数。在这种情况下,它认为列表为<
和junk2
,因为"<"
是由bash和其他shell识别的运算符,而不是正在执行的程序。因此,wc
(由于junk
认为其名称为argv[0]
)尝试将<
作为输入文件打开并失败,请打印消息:
junk: >: open: No such file or directory