【发布时间】:2016-09-06 05:37:47
【问题描述】:
我正在用 C 实现 linux shell,但我的输出重定向似乎无法正常工作。当我运行“ls > testFile”时,我只是得到一个空提示,而我期待“minishell>”,我在打开 testFile 时找到了它。为什么会这样?这是重定向功能本身的问题还是包含重定向的功能的问题? (parse_line 或 process_cmd)
int main(void) {
char cmdline[MAXLINE];
while (1) {
// print prompt
printf("%s", prompt);
fflush(stdout);
// get user input
if (fgets(cmdline, MAXLINE, stdin) == NULL) {
return 1;
} else {
process_cmd(cmdline);
fflush(stdout);
}
}
return 0;
}
void process_cmd(char *cmdline) {
int argc;
char *argv[MAXARGS];
int status;
argc = parse_line(cmdline, argv);
if (argc == 0) {
return;
}
if (builtin_cmd(argc, argv) == 1) {
int pid = fork();
if (pid == 0) {
argv[argc] = NULL;
if (execvp(argv[0], argv) == -1) {
perror ("Error");
}
printf("%s: command not found.\n", argv[0]);
exit(1);
}
wait(&status);
}
return;
}
int parse_line(char *cmdline, char **argv) {
int count = 0;
int isRedirected = -1;
argv[0] = strtok(cmdline, delimiter);
if (argv[0] == NULL) {
return 0;
}
count++;
while(1) {
argv[count] = strtok(NULL, delimiter);
if (argv[count] == NULL) {
break;
}
count++;
}
// redirection check
for (int index = 0; index < count; index++) {
if ((strcmp(argv[index], ">") == 0)) {
if (argv[index+1] == NULL) {
printf("output file missing.\n");
printf("USAGE: [command] > [target_file_name]\n");
return count;
}
isRedirected = redirect(argv[index+1]);
for ( index = index+2; index != count; index++) {
argv[index-2] = argv[index];
}
argv[count-1] = NULL;
argv[count-2] = NULL;
count = count - 2;
break;
}
}
if (isRedirected > 0) {
reverseRedirected(isRedirected);
}
return count;
}
int redirect(char *redirectionDest) {
int stdOutputFd;
int fd = open(redirectionDest,O_CREAT|O_TRUNC|O_WRONLY,S_IRUSR|S_IWUSR);
if ((stdOutputFd = dup(1)) == -1) {
perror("Error");
return -1;
}
if (dup2(fd, 1) == -1) {
perror("Error");
close(stdOutputFd);
return -1;
}
close(fd);
return stdOutputFd;
}
void reverseRedirected(int fd) {
if (dup2(1, fd) == -1) {
printf("fd dup failed!!\n");
exit(0);
}
return;
}
【问题讨论】:
-
除非你喜欢麻烦,否则做fork和exec之间的重定向。这样您就不必取消重定向任何内容,也不必关心(取消)重定向失败的后果。
-
如果它是非内置函数,那会很完美,但如果我想重定向我的内置函数怎么办?还有其他方法可以避免取消重定向吗?
-
也分叉它们(不要执行,只分叉)。
-
很抱歉一次又一次地询问......但我认为“内置函数”的措辞有点模棱两可。 'builtin-cmd' 函数运行我自己编写的函数,而不是位于 /bin 中的 linux 内置函数。它不调用 exec()。我还需要 fork() 吗?
-
我明白这一点。这就是为什么我说“不要执行”。没有什么可以执行的。分叉,重定向,做内置的事情,等待。它比重定向更容易,做内置的事情,重定向回来,处理重定向错误。您已经有了分叉和等待代码。