我正在编写自己的自定义shell,作为我项目的一部分,当程序读取"<"或";;字符从用户输入,它需要重定向标准输入和标准输出到自定义文件。我在下面写了一个函数。我苦苦挣扎的部分是,即使我以相同的方式编写输入和输出重定向的代码,输出重定向似乎按预期工作,而输入重定向却没有。请看下面的代码:
void inOutReDirector(char **toks, char *inputFile, char *outputFile, int *fd0, int *fd1, int *in, int *out) {
fflush(0);
for (int i = 0; toks[i] != NULL; i++) {
if (strcmp(toks[i], "<") == 0) {
toks[i] = NULL;
strcpy(inputFile, toks[i + 1]);
toks[i + 1] = NULL;
*in = 1;
}
if (strcmp(toks[i], ">") == 0) {
toks[i] = NULL;
strcpy(outputFile, toks[i + 1]);
toks[i + 1] = NULL;
*out = 1;
}
}
//input redirection
if (*in == 1) {
if ((*fd0 = open(inputFile, O_RDONLY, 0)) < 0) {
printf("Couldn't open input file: %s", strerror(errno));
exit(1);
}
dup2(*fd0, STDIN_FILENO);
close(*fd0);
}
//output redirection
if (*out == 1) {
if ((*fd1 = creat(outputFile, 0644)) < 0) {
printf("Couldn't open output file: %s", strerror(errno));
exit(1);
}
dup2(*fd1, STDOUT_FILENO);
close(*fd1);
}
}
下面是我如何从main调用这个函数:
int main() {
char *toks[STD_INPUT_SIZE] = {0};
int fd0, fd1, in = 0, out = 0;
char inputFile[64], outputFile[64];
pid_t pid;
while (1) {
//print prompt
//get user input
pid = fork();
if (pid < 0) {
printf("%s n", strerror(errno));
exit(1);
}
int stopNeeded = strcmp(toks[0], "exit") == 0;
if (pid == 0 && !stopNeeded) {
pathFinder(toks, shellInput, currentDir); //finding path for execv input
inOutReDirector(toks, inputFile, outputFile, &fd0, &fd1, &in, &out); // I/O redirection
if (execv(shellInput, toks) != 0) {
char *errMsg = strerror(errno);
printf("%s n", errMsg);
//clean the old contents of toks
for (int i = 0; i < STD_INPUT_SIZE; ++i) {
free(toks[i]);
toks[i] = NULL;
}
exit(1);
}
}
if (pid > 0) {
pid_t childPid = waitpid(pid, NULL, 0);
(void) childPid;
}
}
return 0;
}
下面是一个从我的终端屏幕
输出重定向的例子$ ls > output.txt
$
这会创建"output.txt"文件,并在当前目录中打印该文件中的结果。
下面是一个从终端屏幕
输入重定向的例子$ cat < output.txt
$
输入重定向工作不正确。它打印提示并等待输入,而不是在我的终端中显示output.txt的内容。
感谢您提前提供的任何帮助!
问题应该在函数inOutReDirector
if (strcmp(toks[i], ">") == 0) {
改为
else if (strcmp(toks[i], ">") == 0) {
当toks[i]
等于" "时,上面的toks[i]
将被设置为NULL,调用strcmp的这一行将导致SIGSEGV,因此子进程将退出,后续的execv
将不执行。