gpt4 book ai didi

c - Unix shell 的输入重定向不起作用

转载 作者:行者123 更新时间:2023-11-30 15:11:39 25 4
gpt4 key购买 nike

我发现了同样的问题,但没有答案。

在构建我自己的 unix shell 时,我的输出重定向工作正常,但是当我尝试输入时,它没有执行任何操作。如果你能帮我解决这个问题那就太好了。这是我的执行函数代码:

void execute (char **args)
{
int pid, status;
pid = fork ();

if (pid < 0)
{
perror ("Error forking!");
return;
}


else if (pid > 0)
{
fflush(0);
while (wait (&status) != pid)
continue;
}


else if (pid == 0)
{

int i,in=0,out=0;
char input[BUF_SIZE],output[BUF_SIZE];

for(i=0;args[i]!=NULL;i++)
{
if(strcmp(args[i],"<")==0)
{
args[i]=NULL;
strcpy(input,args[i+1]);
in=2;
}

if(strcmp(args[i],">")==0)
{
args[i]=NULL;
strcpy(output,args[i+1]);
out=2;
}
}


if(in)
{
int fd0;
if ((fd0 = open(input, O_RDONLY, 0)) < 0)
{
perror("Couldn't open input file");
exit(0);
}

dup2(fd0, 0);

close(fd0);
}


if (out)
{
int fd1;
if ((fd1 = creat(output , 0644)) < 0)
{
perror("Couldn't open the output file");
exit(0);
}

dup2(fd1, 1);
close(fd1);
}

execvp (*args, args);
perror("execvp");
_exit(1);
}

这是我的完整代码:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>

#define ARGSIZE 20
#define BUF_SIZE 1024

void execute (char **args);
void cd (char *directory);
int killpid (char *pitstr, int sig);

int main (void)
{
char line[BUF_SIZE] = {0};
char *args[ARGSIZE] = {NULL};
char *token;
int i, argIndex = 0;

while (1)
{

argIndex = 0;

for (i = 0; i < ARGSIZE; i++)
args[i] = NULL;

printf ("shell> ");

if (fgets (line, BUF_SIZE, stdin) == NULL)
{
printf ("EOF received\n");
return 0;
}

if (*line == '\n')
continue;

token = strtok (line, " \n");

while (token != NULL)
{
args[argIndex] = token;
token = strtok (NULL, " \n");
argIndex++;
}

if (!argIndex)
continue;

if (strcmp (args[0], "quit") == 0 || strcmp (args[0], "exit") == 0)
break;

if ((strcmp (args[0], "cd") == 0))
cd (args[1]);
else if ((strcmp (args[0], "kill") == 0))
{
if (args[1])
killpid (args[1], SIGTERM);
}


else
execute (args);

}
return 0;
}

void execute (char **args)
{
int pid, status;
pid = fork ();

if (pid < 0)
{
perror ("Error forking!");
return;
}


else if (pid > 0)
{
fflush(0);
while (wait (&status) != pid)
continue;
}


else if (pid == 0)
{

int i,in=0,out=0;
char input[BUF_SIZE],output[BUF_SIZE];

for(i=0;args[i]!=NULL;i++)
{
if(strcmp(args[i],"<")==0)
{
args[i]=NULL;
strcpy(input,args[i+1]);
in=2;
}

if(strcmp(args[i],">")==0)
{
args[i]=NULL;
strcpy(output,args[i+1]);
out=2;
}
}


if(in)
{
int fd0;
if ((fd0 = open(input, O_RDONLY, 0)) < 0)
{
perror("Couldn't open input file");
exit(0);
}

dup2(fd0, 0);
close(fd0);
}


if (out)
{
int fd1;
if ((fd1 = creat(output , 0644)) < 0)
{
perror("Couldn't open the output file");
exit(0);
}

dup2(fd1, 1);
close(fd1);
}

execvp (*args, args);
perror("execvp");
_exit(1);
}

}

void cd (char *directory)
{
char dir[BUF_SIZE] = {0};

if (!directory)
{
directory = getenv ("HOME");

if (chdir (directory))
fprintf (stderr, "Failed to enter directory: %s\n", directory);
else
printf ("%s\n", directory);

return;
}

if (*directory == '~')
{
strcpy (dir, getenv ("HOME"));
strcat (dir, "/");
strcat (dir, directory + 2);

if (chdir (dir))
fprintf (stderr, "Failed to enter directory: %s\n", dir);
else
printf ("%s\n", dir);

return;
}

if (chdir (directory))
fprintf (stderr, "Failed to enter directory: %s\n", directory);
else
printf ("%s\n", directory);
}

int killpid (char *pidstr, int sig)
{
pid_t pid = (pid_t)atoi (pidstr);

if (pid < 1)
{
fprintf (stderr, "warning: requested pid < 1, ignoring\n");
return (int)pid;
}

printf (" killing pid '%d' with signal '%d'\n", (int)pid, sig);
return 0;
}

最佳答案

当您看到<时在此处的 args 数组中

if(strcmp(args[i],"<")==0)

您将 args[i] 设置为 NULL

    args[i]=NULL;

然后,你将它传递给 strcmp()

if(strcmp(args[i],">")==0)

并且您的子进程将很高兴地出现段错误。使用if-else - 在这里构建:

if(strcmp(args[i],"<")==0) {        
args[i]=NULL;
strcpy(input,args[i+1]);
in=2;
} else if(strcmp(args[i],">")==0) {
args[i]=NULL;
strcpy(output,args[i+1]);
out=2;
}

这应该可以修复错误。

此外,这可能会在检测此类情况时派上用场:

...
while (wait (&status) != pid)
continue;
if (WIFSIGNALED(status))
printf("Killed by signal %d%s\n",
WTERMSIG(status), WCOREDUMP(status)?" (Core dumped)":"");

关于c - Unix shell 的输入重定向不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35523698/

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