我不知道这段代码有什么问题。其输出存在多个错误。该程序应该模仿 UNIX shell。只要不包含任何管道,它就可以正常运行任何命令。然而,当我添加管道时,有趣的事情开始发生。
例如:当我输入 sort < myshell1,c | grep main | cat > o.txt
时
它创建了一个额外的进程。您可以看到这一点,因为在代码中,perror(in)
被执行 4 次(根据 GDB):
COP4338$ sort < myshell1.c | grep main | cat > o.txt
Detaching after fork from child process 16465.
Process ID: 16465
Process ID: 0
in: Success
Detaching after fork from child process 16466.
Process ID: 16466
Process ID: 0
in: Success
Something happened in i != numcommands - 1: Success
Detaching after fork from child process 16468.
Process ID: 16468
COP4338$ Process ID: 0
in: Success
ELSE STATEMENT!
Detaching after fork from child process 17403.
in: Bad address
然后,程序转到新行并且不打印 COP4338$:就像它应该的那样。表现出未定义的行为。我猜测为什么会发生这种情况,因为第四个进程也在继续,因此返回到 main(),就像父进程一样,但我无法确定为什么要创建它。
当我尝试运行 ls -l | cat > o.txt
时,也会出现未定义的行为。
这是 GDB 的输出:
就尝试解决该问题而言,我尚未确定导致此问题的原因。我尝试使用 gdb 调试器通过键入“set follow-fork-mode child”并在第三个子进程的第一行使用断点来调试第三个子进程,但没有任何反应。我只能通过这样做来调试第一个子进程。
/* This code was written by Dr. Raju Rangaswami and was expanded upon as per the instructions in Assignment3, by Michael Duboc(PID: 5706538)*/
#include <stdio.h>
#include <sys/wait.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <string.h>
#define MAX_ARGS 20
#define BUFSIZ 1024
int get_args(char* cmdline, char* args[])
{
int i = 0;
/* if no args */
if((args[0] = strtok(cmdline, "\n\t ")) == NULL)
return 0;
while((args[++i] = strtok(NULL, "\n\t ")) != NULL)
{
if(i >= MAX_ARGS)
{
printf("Too many arguments!\n");
exit(1);
}
}
/* the last one is always NULL */
return i;
}
int customStrCpy(char** line1, char* line2)
{
int strlen1 = strlen(*line1), strlen2 = strlen(line2);
if(strlen1 < strlen2)
{
//Creates a dynamically allocated array that is big enough to store the contents of line2.
*line1 = calloc(strlen2, sizeof(char));
}
strcpy(*line1, line2);
}
void adjustArray(char* args[], int args_itr, int* nargs)
{
int i, j;
for(i = 0; i < 2; i++)
{
for(j = args_itr; j < (*nargs) - 1; j++)
{
customStrCpy(&args[j],args[j+1]);
}
args[(*nargs) - 1] = 0;
(*nargs)--;
}
}
int process(int* greaterthan, int* d_greaterthan, char* args_pipe[], int*
nargs_p, int* fileno_out, int* fileno_in, int* lessthan, FILE** fout,
FILE** fin)
{
int greaterthan_strcmp = strcmp(args_pipe[args_itr], ">");
int d_greaterthan_strcmp = strcmp(args_pipe[args_itr], ">>");
if(greaterthan_strcmp == 0 || d_greaterthan_strcmp == 0)
{
if(greaterthan_strcmp == 0)
*fout = fopen(args_pipe[args_itr + 1], "w");
else
*fout = fopen(args_pipe[args_itr + 1], "a");
*fileno_out = fileno(*fout);
*greaterthan = 1;
adjustArray(args_pipe, args_itr, nargs_p);
args_itr--;
int print_arr;
for(print_arr = 0; print_arr
(sizeof(args_pipe)/sizeof(args_pipe[0])); print_arr++)
printf("%s ",args_pipe[print_arr]);
printf("\n");
}
else if(strcmp(args_pipe[args_itr], "<") == 0)
{
*fin = fopen(args_pipe[args_itr + 1], "r");
*fileno_in = fileno(*fin);
*lessthan = 1;
adjustArray(args_pipe, args_itr, nargs_p);
args_itr--;
}
}
return 0;
}
void execute(char* cmdline)
{
int pid, async, lessthan = 0;
int greaterthan = 0, pipef = 0, d_greaterthan = 0;
int args_itr, pipe_flag = 0;
int flag_count = 0, fileno_in, fileno_out;
char* args_pipe[MAX_ARGS];/*5 and 3 are test numbers.*/
char* args[MAX_ARGS];
int nargs = get_args(cmdline, args);
if(nargs <= 0) return;
if(!strcmp(args[0], "quit") || !strcmp(args[0], "exit"))
{
exit(0);
}
/* check if async call */
if(!strcmp(args[nargs-1], "&")) { async = 1; args[--nargs] = 0; }
else async = 0;
FILE* fout = stdout;
FILE* fin = stdin;
for(args_itr = 0; args_itr < nargs; args_itr++)
{
if(!strcmp(args[args_itr], "|")) {pipe_flag = 1; flag_count++;}
}
if(pipe_flag)
{
int num_commands = flag_count + 1, i = 0, j = 0;
int fd[num_commands][2];
for(i = 0; i < flag_count; i++) {pipe(fd[i]);}
for(i = 0; i < num_commands; i++)
{
int nargs_p = 0, args_pipe_itr = 0;
while(j < nargs && strcmp(args[j], "|"))
{//Possibly make into for loop.
args_pipe[args_pipe_itr] = args[j];
args_pipe_itr++;
j++;
nargs_p++;
}
j++;
int pid = fork();
signal(SIGTTIN, SIG_IGN);
signal(SIGTTOU, SIG_IGN);
printf("Process ID: %d\n", pid);
if(pid < 0)
{
perror("Error forking!");
return;
}
else if(pid > 0) {continue;}
else //pid == 0
{
perror("in");
if(i == 0)
{
process(&greaterthan, &d_greaterthan, &args_pipe[i] ,&nargs_p, &fileno_out, &fileno_in, &lessthan, &fout, &fin);
printf("Lessthan = %d", lessthan);
if(lessthan) dup2(fileno_in, STDIN_FILENO);
dup2(fd[i][1], STDOUT_FILENO);
}
else if(i != num_commands - 1)
{
dup2(fd[i - 1][1], STDIN_FILENO);
//process(&greaterthan, &d_greaterthan, &args_pipe[i] ,&nargs_p, &fileno_out, &fileno_in, &lessthan, &fout, &fin);
dup2(fd[i][1], STDOUT_FILENO);
}
else
{
dup2(fd[i - 1][1], STDIN_FILENO);
process(&greaterthan, &d_greaterthan, &args_pipe[i] ,&nargs_p, &fileno_out, &fileno_in, &lessthan, &fout, &fin);
printf("greaterthan = %d", greaterthan);
printf("d_greaterthan = %d", d_greaterthan);
if(greaterthan || d_greaterthan) dup2(fileno_out, STDOUT_FILENO);
}
int close_pipes;
for(close_pipes = 0; close_pipes < flag_count; close_pipes++)
{
//close(fd[i][0]); close(fd[i][1]); JUST, WHY?!? THIS IS WHAT HAPPENS WHEN YOU DON'T THINK!
close(fd[close_pipes][0]);
close(fd[close_pipes][1]);
}
if(fout != stdout) fclose(fout);
if(fin != stdin) fclose(fin);
execvp(args_pipe[0], args_pipe);
perror("Something happened.");
exit(-1);
}//end child.
}
for(i = 0; i < flag_count; i++) {close(fd[i][0]); close(fd[i][1]);}
return;
}
}
int main (int argc, char* argv [])
{
for(;;)
{
printf("COP4338$ ");
if(fgets(cmdline, BUFSIZ, stdin) == NULL)
{
perror("fgets failed");
exit(1);
}
execute(cmdline);
int corpse;
int status;
while(corpse = wait(%status)) > 0)
perror(pid %d exited with status: 0x%.4X\n, corpse, status);
}
}
程序应该将“int main (int argc, char* argv [])
”打印到o.txt,但o.txt根本没有改变。
对于那些好奇的人来说,函数 process() 会扫描构成命令的参数字符串,并根据程序看到的符号设置标志。
最佳答案
您的代码存在一些问题:
- 不调用
wait()
或等效函数。 - 将管道的错误一端连接到标准输入或标准输出。
- 访问参数组的错误部分 - 命令名称和参数。
- 关闭错误的管道文件描述符,可能会重复关闭。
我认为 customStrCpy()
函数和 adjustArray()
函数中存在内存泄漏和不必要的内存分配问题,但我还没有解决这些问题 -当您不需要担心泄漏时,代码似乎可以正常工作。
我需要添加诊断来找出您的代码做错了什么。因此,我使用了我的 SOQ 中提供的错误报告代码。 (堆栈溢出问题)GitHub 上的存储库为 src/libsoq 中的文件 stderr.c
和 stderr.h
子目录。
此代码基于 Revision 6 中显示的代码问题的内容 - 问题中显示的代码自那时起已被修改。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/wait.h>
#include <unistd.h>
#include "stderr.h"
#define MAX_ARGS 20
#define BUFSIZ 1024
static
int get_args(char *cmdline, char *args[])
{
int i = 0;
/* if no args */
if ((args[0] = strtok(cmdline, "\n\t ")) == NULL)
return 0;
while ((args[++i] = strtok(NULL, "\n\t ")) != NULL)
{
if (i >= MAX_ARGS)
{
printf("Too many arguments!\n");
exit(1);
}
}
/* the last one is always NULL */
return i;
}
static
void customStrCpy(char **line1, char *line2)
{
int strlen1 = strlen(*line1), strlen2 = strlen(line2);
if (strlen1 < strlen2)
{
// Creates a dynamically allocated array that is big enough to store the contents of line2.
*line1 = calloc(strlen2, sizeof(char));
}
strcpy(*line1, line2);
}
static
void adjustArray(char *args[], int args_itr, int *nargs)
{
int i, j;
for (i = 0; i < 2; i++)
{
for (j = args_itr; j < (*nargs) - 1; j++)
{
customStrCpy(&args[j], args[j + 1]);
}
args[(*nargs) - 1] = 0;
(*nargs)--;
}
}
static
void process(int *greaterthan, int *d_greaterthan, char *args_pipe[],
int *nargs_p, int *fileno_out, int *fileno_in, int *lessthan,
FILE **fout, FILE **fin)
{
int args_itr;
err_remark("-->> %s():\n", __func__);
for (args_itr = 0; args_itr < *nargs_p; args_itr++)
{
if (strcmp(args_pipe[args_itr], ">") == 0)
{
err_remark("---- %s(): > %s\n", __func__, args_pipe[args_itr + 1]);
*fout = fopen(args_pipe[args_itr + 1], "w");
if (fout == NULL)
err_syserr("failed to open file '%s' for writing\n",
args_pipe[args_itr + 1]);
*fileno_out = fileno(*fout);
*greaterthan = 1;
adjustArray(args_pipe, args_itr, nargs_p);
args_itr--;
}
else if (strcmp(args_pipe[args_itr], ">>") == 0)
{
err_remark("---- %s(): >> %s\n", __func__, args_pipe[args_itr + 1]);
*fout = fopen(args_pipe[args_itr + 1], "a");
if (fout == NULL)
err_syserr("failed to open file '%s' for appending\n",
args_pipe[args_itr + 1]);
*fileno_out = fileno(*fout);
*d_greaterthan = 1;
adjustArray(args_pipe, args_itr, nargs_p);
args_itr--;
}
else if (strcmp(args_pipe[args_itr], "<") == 0)
{
err_remark("---- %s(): < %s\n", __func__, args_pipe[args_itr + 1]);
*fin = fopen(args_pipe[args_itr + 1], "r");
if (fin == NULL)
err_syserr("failed to open file '%s' for reading\n",
args_pipe[args_itr + 1]);
*fileno_in = fileno(*fin);
*lessthan = 1;
adjustArray(args_pipe, args_itr, nargs_p);
args_itr--;
}
}
err_remark("<<-- %s()\n", __func__);
}
static
void execute(char *cmdline)
{
int lessthan = 0;
int greaterthan = 0, d_greaterthan = 0;
int args_itr, pipe_flag = 0;
int flag_count = 0, fileno_in, fileno_out;
char *args_pipe[MAX_ARGS];/*5 and 3 are test numbers.*/
char *args[MAX_ARGS];
int nargs = get_args(cmdline, args);
if (nargs <= 0)
return;
if (!strcmp(args[0], "quit") || !strcmp(args[0], "exit"))
{
exit(0);
}
for (int x = 0; x < nargs; x++)
err_remark("args[%d] = [%s]\n", x, args[x]);
FILE *fout = stdout;
FILE *fin = stdin;
for (args_itr = 0; args_itr < nargs; args_itr++)
{
if (!strcmp(args[args_itr], "|"))
{
pipe_flag = 1;
flag_count++;
}
}
if (pipe_flag)
{
int num_commands = flag_count + 1, i = 0, j = 0;
int fd[flag_count][2];
for (i = 0; i < flag_count; i++)
{
pipe(fd[i]);
err_remark("opened pipe - %d and %d\n", fd[i][0], fd[i][1]);
}
for (i = 0; i < num_commands; i++)
{
int nargs_p = 0, args_pipe_itr = 0;
while (j < nargs && strcmp(args[j], "|"))
{
// Possibly make into for loop.
args_pipe[args_pipe_itr] = args[j];
args_pipe_itr++;
j++;
nargs_p++;
}
args_pipe[nargs_p] = NULL; /* JL: Null-terminate argument list */
j++; /* Skip pipe argument */
int pid = fork();
signal(SIGTTIN, SIG_IGN);
signal(SIGTTOU, SIG_IGN);
if (pid < 0)
{
err_syserr("failed to fork a child process: ");
/*NOTREACHED*/
}
if (pid > 0)
{
err_remark("Parent launched child %d\n", pid);
continue;
}
else // if (pid == 0)
{
err_remark("child at work (i == %d)\n", i);
if (i == 0)
{
err_remark("first process in pipeline (i = %d, j = %d)\n", i, j);
process(&greaterthan, &d_greaterthan, args_pipe,
&nargs_p, &fileno_out, &fileno_in, &lessthan,
&fout, &fin);
if (lessthan)
dup2(fileno_in, STDIN_FILENO);
dup2(fd[i][1], STDOUT_FILENO);
}
else if (i != num_commands - 1)
{
err_remark("middle process in pipeline (i = %d, j = %d)\n", i, j);
dup2(fd[i - 1][0], STDIN_FILENO); /* JL */
/* Will need to process I/O redirections mid-pipeline */
/* However, they're always a bug in the shell script */
dup2(fd[i][1], STDOUT_FILENO);
}
else
{
err_remark("final process in pipeline (i = %d, j = %d)\n", i, j);
dup2(fd[i - 1][0], STDIN_FILENO); /* JL */
process(&greaterthan, &d_greaterthan, args_pipe,
&nargs_p, &fileno_out, &fileno_in, &lessthan,
&fout, &fin);
if (greaterthan || d_greaterthan)
err_remark("Redirection:\n"),
dup2(fileno_out, STDOUT_FILENO);
}
err_remark("close pipes\n");
int close_pipes;
for (close_pipes = 0; close_pipes < flag_count; close_pipes++)
{
close(fd[close_pipes][0]); /* JL */
close(fd[close_pipes][1]); /* JL */
}
if (fout != stdout)
fclose(fout);
if (fin != stdin)
fclose(fin);
err_remark("execute command [%s]\n", args_pipe[0]);
for (int i = 1; args_pipe[i] != NULL; i++)
err_remark("argument %d [%s]\n", i, args_pipe[i]);
execvp(args_pipe[0], args_pipe);
err_syserr("Failed to execute (i=%d) '%s': ", i, args_pipe[0]);
/*NOTREACHED*/
}// end child.
}
/* Parent process closes its copy of each pipe */
for (i = 0; i < flag_count; i++)
{
close(fd[i][0]);
close(fd[i][1]);
}
return;
}
else
err_remark("No pipe in input - no command executed\n");
}
int main(int argc, char **argv)
{
if (argc >= 0)
err_setarg0(argv[0]);
err_setlogopts(ERR_PID|ERR_MILLI);
for ( ; ; )
{
printf("COP4338$ ");
char cmdline[BUFSIZ];
if (fgets(cmdline, BUFSIZ, stdin) == NULL)
{
printf("EOF\n");
exit(1);
}
execute(cmdline);
int status;
int corpse;
while ((corpse = wait(&status)) > 0)
err_remark("PID %d exited with status 0x%.4X\n", corpse, status);
}
}
process()
函数不需要区分参数列表中的 >
和 >>
;正确处理标准输出就足够了。调用代码会更简单。我不相信您应该使用 fopen()
- 使用带有适当控制参数的 open()
会更明智。
但是,这至少看起来有效。源代码为shell61.c
,编译为程序shell61
。
$ shell61
COP4338$ sort < shell61.c | grep main | cat > o.txt
shell61: 2019-05-04 22:17:39.982 - pid=8150: args[0] = [sort]
shell61: 2019-05-04 22:17:39.983 - pid=8150: args[1] = [<]
shell61: 2019-05-04 22:17:39.983 - pid=8150: args[2] = [shell61.c]
shell61: 2019-05-04 22:17:39.983 - pid=8150: args[3] = [|]
shell61: 2019-05-04 22:17:39.983 - pid=8150: args[4] = [grep]
shell61: 2019-05-04 22:17:39.983 - pid=8150: args[5] = [main]
shell61: 2019-05-04 22:17:39.983 - pid=8150: args[6] = [|]
shell61: 2019-05-04 22:17:39.983 - pid=8150: args[7] = [cat]
shell61: 2019-05-04 22:17:39.983 - pid=8150: args[8] = [>]
shell61: 2019-05-04 22:17:39.983 - pid=8150: args[9] = [o.txt]
shell61: 2019-05-04 22:17:39.983 - pid=8150: opened pipe - 3 and 4
shell61: 2019-05-04 22:17:39.983 - pid=8150: opened pipe - 5 and 6
shell61: 2019-05-04 22:17:39.984 - pid=8150: Parent launched child 8153
shell61: 2019-05-04 22:17:39.984 - pid=8150: Parent launched child 8154
shell61: 2019-05-04 22:17:39.984 - pid=8150: Parent launched child 8155
shell61: 2019-05-04 22:17:39.984 - pid=8154: child at work (i == 1)
shell61: 2019-05-04 22:17:39.984 - pid=8153: child at work (i == 0)
shell61: 2019-05-04 22:17:39.984 - pid=8155: child at work (i == 2)
shell61: 2019-05-04 22:17:39.985 - pid=8154: middle process in pipeline (i = 1, j = 7)
shell61: 2019-05-04 22:17:39.985 - pid=8155: final process in pipeline (i = 2, j = 11)
shell61: 2019-05-04 22:17:39.985 - pid=8153: first process in pipeline (i = 0, j = 4)
shell61: 2019-05-04 22:17:39.985 - pid=8154: close pipes
shell61: 2019-05-04 22:17:39.985 - pid=8155: -->> process():
shell61: 2019-05-04 22:17:39.985 - pid=8153: -->> process():
shell61: 2019-05-04 22:17:39.986 - pid=8154: execute command [grep]
shell61: 2019-05-04 22:17:39.986 - pid=8155: ---- process(): > o.txt
shell61: 2019-05-04 22:17:39.986 - pid=8153: ---- process(): < shell61.c
shell61: 2019-05-04 22:17:39.986 - pid=8154: argument 1 [main]
shell61: 2019-05-04 22:17:39.986 - pid=8155: <<-- process()
shell61: 2019-05-04 22:17:39.986 - pid=8153: <<-- process()
shell61: 2019-05-04 22:17:39.987 - pid=8155: Redirection:
shell61: 2019-05-04 22:17:39.987 - pid=8153: close pipes
shell61: 2019-05-04 22:17:39.987 - pid=8155: close pipes
shell61: 2019-05-04 22:17:39.987 - pid=8153: execute command [sort]
shell61: 2019-05-04 22:17:39.988 - pid=8155: execute command [cat]
shell61: 2019-05-04 22:17:39.993 - pid=8150: PID 8153 exited with status 0x0000
shell61: 2019-05-04 22:17:39.993 - pid=8150: PID 8154 exited with status 0x0000
shell61: 2019-05-04 22:17:39.994 - pid=8150: PID 8155 exited with status 0x0000
COP4338$ cat o.txt | cat
shell61: 2019-05-04 22:18:08.339 - pid=8150: args[0] = [cat]
shell61: 2019-05-04 22:18:08.339 - pid=8150: args[1] = [o.txt]
shell61: 2019-05-04 22:18:08.339 - pid=8150: args[2] = [|]
shell61: 2019-05-04 22:18:08.339 - pid=8150: args[3] = [cat]
shell61: 2019-05-04 22:18:08.339 - pid=8150: opened pipe - 3 and 4
shell61: 2019-05-04 22:18:08.340 - pid=8150: Parent launched child 8157
shell61: 2019-05-04 22:18:08.340 - pid=8150: Parent launched child 8158
shell61: 2019-05-04 22:18:08.340 - pid=8157: child at work (i == 0)
shell61: 2019-05-04 22:18:08.340 - pid=8158: child at work (i == 1)
shell61: 2019-05-04 22:18:08.340 - pid=8157: first process in pipeline (i = 0, j = 3)
shell61: 2019-05-04 22:18:08.341 - pid=8157: -->> process():
shell61: 2019-05-04 22:18:08.341 - pid=8158: final process in pipeline (i = 1, j = 5)
shell61: 2019-05-04 22:18:08.341 - pid=8157: <<-- process()
shell61: 2019-05-04 22:18:08.341 - pid=8158: -->> process():
shell61: 2019-05-04 22:18:08.342 - pid=8157: close pipes
shell61: 2019-05-04 22:18:08.342 - pid=8158: <<-- process()
shell61: 2019-05-04 22:18:08.342 - pid=8157: execute command [cat]
shell61: 2019-05-04 22:18:08.342 - pid=8158: close pipes
shell61: 2019-05-04 22:18:08.343 - pid=8157: argument 1 [o.txt]
shell61: 2019-05-04 22:18:08.343 - pid=8158: execute command [cat]
int main(int argc, char **argv)
shell61: 2019-05-04 22:18:08.347 - pid=8150: PID 8158 exited with status 0x0000
shell61: 2019-05-04 22:18:08.347 - pid=8150: PID 8157 exited with status 0x0000
COP4338$ ls
shell61: 2019-05-04 22:18:41.516 - pid=8150: args[0] = [ls]
shell61: 2019-05-04 22:18:41.516 - pid=8150: No pipe in input - no command executed
COP4338$ exit
$
当我首先添加 wait()
代码时,我收到如下消息:
$ shell61
COP4338$ ls | grep shell
shell61: 2019-05-04 14:29:23.201 - pid=5181: args[0] = [ls]
shell61: 2019-05-04 14:29:23.202 - pid=5181: args[1] = [|]
shell61: 2019-05-04 14:29:23.202 - pid=5181: args[2] = [grep]
shell61: 2019-05-04 14:29:23.202 - pid=5181: args[3] = [shell]
shell61: 2019-05-04 14:29:23.202 - pid=5181: opened pipe - 3 and 4
Process ID: 5182
Process ID: 5183
Process ID: 0
Process ID: 0
shell61: 2019-05-04 14:29:23.203 - pid=5183: child at work
PID 5183 exited with status 0x000B
shell61: 2019-05-04 14:29:23.203 - pid=5182: child at work
PID 5182 exited with status 0x000D
COP4338$ exit
$
5183 的退出状态是 0x000B,翻译过来就是“死于信号 11 — SIGSEGV”; 5182 的退出状态是 0x000D,它翻译为“死于信号 13 — SIGPIPE”。这是重要的信息。特别是通过 err_remark() 添加的打印有助于显示问题所在。发现您使用 &args_pipe[i]
而不是 &args_pipe[0]
或 args_pipe
调用 process()
是 key 也是。
当跟踪看起来像:
$ shell61
COP4338$ ls | grep shell
shell61: 2019-05-04 16:24:24.297 - pid=6417: args[0] = [ls]
shell61: 2019-05-04 16:24:24.298 - pid=6417: args[1] = [|]
shell61: 2019-05-04 16:24:24.298 - pid=6417: args[2] = [grep]
shell61: 2019-05-04 16:24:24.298 - pid=6417: args[3] = [shell]
shell61: 2019-05-04 16:24:24.298 - pid=6417: opened pipe - 3 and 4
shell61: 2019-05-04 16:24:24.299 - pid=6417: Parent launched child 6419
shell61: 2019-05-04 16:24:24.299 - pid=6417: Parent launched child 6420
shell61: 2019-05-04 16:24:24.300 - pid=6420: child at work (i == 1)
shell61: 2019-05-04 16:24:24.299 - pid=6419: child at work (i == 0)
shell61: 2019-05-04 16:24:24.300 - pid=6420: final process in pipeline (i = 1, j = 5)
shell61: 2019-05-04 16:24:24.301 - pid=6419: first process in pipeline (i = 0, j = 2)
shell61: 2019-05-04 16:24:24.301 - pid=6420: -->> process():
shell61: 2019-05-04 16:24:24.302 - pid=6420: <<-- process()
greaterthan = 0
d_greaterthan = 0
shell61: 2019-05-04 16:24:24.302 - pid=6419: -->> process():
shell61: 2019-05-04 16:24:24.302 - pid=6420: close pipes
shell61: 2019-05-04 16:24:24.302 - pid=6419: <<-- process()
Lessthan = 0
shell61: 2019-05-04 16:24:24.303 - pid=6420: execute command [grep]
shell61: 2019-05-04 16:24:24.303 - pid=6420: argument 1 [shell]
shell61: 2019-05-04 16:24:24.303 - pid=6419: close pipes
shell61: 2019-05-04 16:24:24.304 - pid=6419: execute command [ls]
grep: (standard input): Bad file descriptor
PID 6420 exited with status 0x0100
PID 6419 exited with status 0x000D
COP4338$ exit
$
很明显,重定向存在问题 - 不清楚标准输入是否已关闭,或者 grep
是否被要求从只写文件描述符中读取;代码审查显示后者实际上是问题所在(在需要使用 fd[i][0]
的地方使用 fd[i][1]
)。
我无法充分强调拥有强大而简单的错误报告工具的帮助。我在大多数程序中使用 stderr.c
和 stderr.h
代码 - 我很少不使用它们。您应该获取它们的副本或设计自己的等效版本,但请注意该代码经过 30 年的改进(尽管有些年我没有对其进行任何更改 - 2018 年是最近的一年) ,但在 1992-1995 年以及此后的其他年份中都没有改变)。我还保留着的最早版本是 1988 年的;代码实际上是在此之前启动的,但是我在移 Action 业时未能成功传输数据(事实证明8英寸软盘是一个糟糕的选择)。
关于c - C 的管道问题。是否有额外的进程正在执行?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55931016/