【发布时间】:2021-09-17 08:18:03
【问题描述】:
我有一个任务,我需要在 C 中创建一个 shell。其中一项规范是在输入重定向符号 ('fgets 读取来自stdin 的输入。读取输入后,saved_stdin恢复正常输入流。
但是,在第一次重定向输入时,它可以完美运行。然后,在那之后的时间里,没有从stdin 读取任何内容。我已经尝试调试好几次,但找不到我的错误。非常感谢您的帮助!
我的代码如下,以便您能够重现错误,并帮助我纠正我的错误。另外,请确保在您运行程序的目录中创建一个名为text.txt 的文件。 text.txt的内容:
hello, how are you?
请注意,代码非常简化,我只是使用硬编码参数。在我的实际实现中,输入是由用户给出的(我 100% 确定接收输入没有任何问题)。
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdbool.h>
#include <stdio.h>
#define MAX_ARG_LENGTH 100
int redir_in(char **args, int in_pos);
void echo();
void reset();
// Global Variables
int saved_stdin;
bool changed_in;
int main(void)
{
// sample arguments (args)
char *args[MAX_ARG_LENGTH] = {"echo", "<", "text.txt"};
// position of '<'
int pos = 1;
printf("output 1: ");
if(redir_in(args, pos) == 0){
echo();
reset();
}
printf("\noutput 2: ");
if(redir_in(args, pos) == 0){
echo();
reset();
}
printf("\nexiting...\n");
return 0;
}
void echo()
{
char line[MAX_ARG_LENGTH];
while(fgets(line, MAX_ARG_LENGTH, stdin) != NULL)
printf("%s", line);
}
// args is an array of inputted string arguments, in_pos is the index
// of '<' in the array
int redir_in(char **args, int in_pos)
{
char *file_name;
file_name = args[in_pos + 1];
int fd;
fd = open(file_name, O_RDONLY, S_IRUSR);
if (fd < 0)
return -1;
saved_stdin = dup(0);
dup2(fd, STDIN_FILENO);
close(fd);
changed_in = true;
return 0;
}
void reset()
{
if(changed_in){
dup2(saved_stdin, 0);
close(saved_stdin);
changed_in = false;
}
}
预期输出:
output 1: hello, how are you?
output 2: hello, how are you?
exiting...
我得到的输出:
output 1: hello, how are you?
output 2:
exiting...
【问题讨论】:
-
请edit您的问题并添加更多关于我们如何重现问题的详细信息。显示您使用的输入(
text.txt的内容)、实际和预期输出,并在必要时描述实际输出错误的原因。 -
@Bodo 感谢您的反馈。我按要求更新了问题。
-
我无法重现问题,我得到了预期的输出。见onlinegdb.com/DVz2ZNk0Q
-
您是否准确地测试了问题中的代码?我不知道为什么它的行为可能会有所不同。我不确定,但我认为在
reset()中你应该在dup2(saved_stdin, STDIN_FILENO);之前close(STDIN_FILENO)。除此之外,我建议检查所有返回值是否有错误指示。并且没有参数的函数应该写成void echo(void);等(C不是C++) -
当您将参数传递给您的程序时,您是否正确地转义了命令行中的
<?因为如果你不这样做,它会被你的命令 shell 解释而不是传递给你的程序。