gpt4 book ai didi

c - Unix Shell 在 C 中实现 Cat - 文件描述符问题

转载 作者:太空宇宙 更新时间:2023-11-04 07:40:05 24 4
gpt4 key购买 nike

我已经完成了 Unix shell 的实践实现,除了我在实现 cat遇到问题当它的输出是一个文件时;即:cat foo.txt > bar.txt - 输出 foo的内容到bar .

让我们从主函数开始,然后定义子方法:

int main(int argc, char **argv)
{
printf("[MYSHELL] $ ");

while (TRUE) {
user_input = getchar();
switch (user_input) {

case EOF:
exit(-1);

case '\n':
printf("[MYSHELL] $ ");
break;

default:
// parse input into cmd_argv - store # commands in cmd_argc
handle_user_input();

//determine input and execute foreground/background process
execute_command();
}
background = 0;
}
printf("\n[MYSHELL] $ ");
return 0;
}

handle_user_input 只是填充 cmd_argv执行 user_input 的数组, 并删除 >并设置一个 output标记用户是否希望输出到文件。这是该方法的核心:

while (buffer_pointer != NULL) { 
cmd_argv[cmd_argc] = buffer_pointer;
buffer_pointer = strtok(NULL, " ");

if(strcmp(cmd_argv[cmd_argc], ">") == 0){
printf("\nThere was a '>' in %s @ index: %d for buffer_pointer: %s \n", *cmd_argv,cmd_argc,buffer_pointer);
cmd_argv[cmd_argc] = strtok(NULL, " ");
output = 1;
}

cmd_argc++;

if(output){
filename = buffer_pointer;
printf("The return of handling input for filename %s = %s + %s \n", buffer_pointer, cmd_argv[0], cmd_argv[1]);
return;
}
}

execute_command 然后被调用,解释现在填充的 cmd_argv .只是为了让您了解大局。显然,这些情况都不匹配,并且 create_process方法被调用:

int execute_command()
{
if (strcmp("pwd", cmd_argv[0]) == 0){
printf("%s\n",getenv("PATH"));
return 1;
}
else if(strcmp("cd", cmd_argv[0]) == 0){
change_directory();
return 1;
}
else if (strcmp("jobs", cmd_argv[0]) == 0){
display_job_list();
return 1;
}
else if (strcmp("kill", cmd_argv[0]) == 0){
kill_job();
}
else if (strcmp("EOT", cmd_argv[0]) == 0){
exit(1);
}
else if (strcmp("exit", cmd_argv[0]) == 0){
exit(-1);
}
else{
create_process();
return;
}
}

很直接,对吧?


create_process 是我遇到问题的地方。

void create_process()
{
status = 0;
int pid = fork();
background = 0;

if (pid == 0) {
// child process
if(output){
printf("Output set in create process to %d\n",output);
output = 0;
int output_fd = open(filename, O_RDONLY);
printf("Output desc = %d\n",output_fd);
if (output_fd > -1) {
dup2(output_fd, STDOUT_FILENO);
close(output_fd);
} else {
perror("open");
}
}
printf("Executing command, but STDOUT writing to COMMAND PROMPT instead of FILE - as I get the 'open' error above \n");
execvp(*cmd_argv,cmd_argv);
// If an error occurs, print error and exit
fprintf (stderr, "unknown command: %s\n", cmd_argv[0]);
exit(0);
} else {
// parent process, waiting on child process
waitpid(pid, &status, 0);
if (status != 0)
fprintf (stderr, "error: %s exited with status code %d\n", cmd_argv[0], status);
}
return;
}

我打印的 output_fd = -1 , 我设法得到 perror("open")在 else 里面说明:open: No such file or directory .然后打印它是 "writing to COMMAND PROMPT instead of FILE" ,正如我向控制台显示的那样。然后执行execvp处理 cat foo.txt , 但将其打印到控制台而不是文件。

我意识到现在不应该,因为有 output_fd = -1不可取,应该返回另一个值;但我无法弄清楚如何正确使用文件描述符以使用 cat foo.txt > bar.txt 打开新的/现有文件并写入它,以及返回命令行的标准输入。

我已经设法输出到文件,但随后无法取回正确的标准输入。有人可以指导我吗?我觉得我正在绕圈子做一些我做错了或正在看的愚蠢的事情。

非常感谢任何帮助。

最佳答案

如果要写入文件为什么要使用O_RDONLY?我的猜测是你应该使用类似的东西:

int output_fd = open(filename, O_WRONLY|O_CREAT, 0666);

(0666是创建时设置访问权限)

很明显,如果您无法打开编辑的文件,则不应启动该命令。

关于c - Unix Shell 在 C 中实现 Cat - 文件描述符问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5121397/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com