c - 系统功能不输出任何东西
问题描述
我一直在修补管道和父子通信,只是现在我使用system
函数调用将某些东西从子传递给父。问题是我相信system
在我的示例中并没有任何输出。
父母读取输入并将其发送给孩子以检查字符串是否为“排序字母”。字符必须按字典顺序排列。我曾经system
组合echo
并将grep
结果发送回管道。我能够将其缩小到管道的父级读取端;它阻塞。我猜那是因为管道中没有任何东西可以读取,并且写入端没有关闭。我知道这将是问题的原因,为了有意义,system
不必输出任何东西。
/*
$ ./grep
AeIoU
Yes.
blah
No.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <ctype.h>
#define STRING_SIZE 128
static void fatalError(char* message);
int checkIfAlpha(char *string, int length); //f-ja koja proverava da li se string sastroji samo od slova
int main(int argc, char const *argv[])
{
pid_t pid;
char input[STRING_SIZE]; //cuvamo input string ovde
char command[100 + STRING_SIZE];
int pipeToParent[2], pipeToChild[2];
int n;
char tmp[50];
int count;
if (pipe(pipeToParent) < 0)
fatalError("pipe error");
if (pipe(pipeToChild) < 0)
fatalError("pipe error");
if ((pid = fork()) < 0)
fatalError("fork error");
else if (pid == 0) {
//child
if (close(pipeToChild[1]) < 0)
fatalError("close error");
if (close(pipeToParent[0]) < 0)
fatalError("close error");
if (dup2(pipeToParent[1], STDOUT_FILENO) < 0)
fatalError("dup2 error");
while (1) {
if ((count = read(pipeToChild[0], tmp, 50)) < 0)
fatalError("read error");
fprintf(stderr, "2\n");
if (count == 0)
break;
sprintf(command, "echo '%s' | grep -i ^a*b*c*d*e*f*g*h*i*j*k*l*m*n*o*p*q*r*s*t*u*v*w*x*y*z*$", tmp);
if (system(command) < 0)
fatalError("system error");
fprintf(stderr, "3\n");
}
exit(EXIT_SUCCESS);
}
//parent
if (close(pipeToParent[1]) < 0)
fatalError("close rror");
if (close(pipeToChild[0]) < 0)
fatalError("close error");
while(fgets(input, STRING_SIZE, stdin) != NULL) {
input[strlen(input)-1] = '\0';
if (checkIfAlpha(input, strlen(input)) == -1) {
fprintf(stderr, "Samo slova\n");
continue;
}
if (write(pipeToChild[1], input, strlen(input)) != strlen(input))
fatalError("write error");
printf("1\n");
if ((n = read(pipeToParent[0], input, STRING_SIZE)) < 0)
fatalError("fatal error");
printf("4\n");
if (n == 0)
printf("No\n");
else if (n > 0)
printf("Yes\n");
}
exit(EXIT_SUCCESS);
}
static void fatalError(char *message) {
perror(message);
exit(EXIT_FAILURE);
}
int checkIfAlpha(char *string , int length) {
int c = 1;
for (int i = 0; i < length; i++)
if (!isalpha(string[i])) {
c = -1;
break;
}
return c;
}
编辑: 如果我认为它们会那么重要,我会发布输出,但无论如何。
这是输出(使用正确的输入):
./grep
abcde
1
2
3
这是GDB:
Temporary breakpoint 1, main (argc=1, argv=0x7fffffffe058) at grep.c:23
23 {
(gdb) next
34 if (pipe(pipeToParent) < 0)
(gdb)
37 if (pipe(pipeToChild) < 0)
(gdb)
40 if ((pid = fork()) < 0)
(gdb)
42 else if (pid == 0) {
(gdb)
76 if (close(pipeToParent[1]) < 0)
(gdb)
80 if (close(pipeToChild[0]) < 0)
(gdb)
83 while(fgets(input, STRING_SIZE, stdin) != NULL) {
(gdb)
85 input[strlen(input)-1] = '\0';
(gdb)
88 if (checkIfAlpha(input, strlen(input)) == -1) {
(gdb)
92 if (write(pipeToChild[1], input, strlen(input)) != strlen(input))
(gdb)
94 printf("1\n");
(gdb)
1
96 if ((n = read(pipeToParent[0], input, STRING_SIZE)) < 0)
(gdb)
解决方案
read
不写入终止空字符。之后if ((count = read(pipeToChild[0], tmp, 50)) < 0)
,程序将 传递tmp
给 ,但不向其中写入空字符sprintf
。
这导致echo
命令从管道读取的数据之外传递额外的垃圾数据tmp
,这反过来又导致grep
找不到匹配的字符串。
一种解决方法是更改read
toread(pipeToChild[0], tmp, sizeof tmp - 1)
和 insert tmp[count] = 0;
。
推荐阅读
- java - JMS如何读取队列中的多个文件
- applescript - “告诉应用程序'邮件'”将不接受来自 AppleScript-ObjC 应用程序中 IBOutlet 的字符串
- mysql - 保存 MySQL 空间数据 Google maps API Bounds
- r - 将时间序列分解为 R 中多个组的趋势、季节性和随机,以获取月度数据
- java - Java检查开始日期和结束日期是否在间隔内
- javascript - 将包装器添加到元素,然后读取 offsetTop 会返回错误的结果
- python - 如何在 Python 中最好地展平 NDJson 数据
- deployment - 谷歌云计算引擎无法部署
- maven - 是否应该在子 pom 或父 pom 中处理排除项?
- java - 如何在Java中循环遍历图像时设置自定义RGB值