【问题标题】:Script bash write in a fifo and c program read from it脚本 bash 写入 fifo 并从中读取 c 程序
【发布时间】:2014-09-18 09:30:11
【问题描述】:

我有一个写入 fifo 的 bash 脚本。我有一个从同一个 fifo 读取的 C 程序。

我确信脚本可以正常工作,因为我尝试使用另一个脚本从 fifo 读取数据并且一切正常。但是有些东西在 C 程序中不起作用。当我运行我的脚本和运行 C 程序时,就像他们在等待对方一样。这是代码。

脚本是(作者):

#!/bin/bash

fifo_name="myfifo";

# Se non esiste, crea la fifo;
[ -p $fifo_name ] || mkfifo $fifo_name;

echo "3" > $fifo_name;
echo "6" > $fifo_name;

这里是 c 程序(读者):

#include <fcntl.h>
#include <stdio.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>

#define MAX_BUF 1024

int main(int argc, char *argv[])
{
    int fd, i;
    char * myfifo = argv[1];
    char buf[MAX_BUF];

    fd = open(myfifo, O_RDONLY);

    while (1) {
        if(read(fd, buf, MAX_BUF) > 0)
        {
            printf("Received: %s\n", buf);      
        }
    }

    close(fd);

    return 0;
}

我哪里错了?

谢谢。

【问题讨论】:

  • 一方面,在假设open() 调用成功并走向悬崖之前,不要检查它的结果。我猜,没有打破while循环的机制是一种奖励。

标签: c bash pipe fifo writer


【解决方案1】:

只要您执行以下操作,它就可以正常工作。

  • 确保在运行 C 程序时,为 FIFO 文件提供具有正确路径名的参数。

  • 首先运行 shell 程序,因为它会在 FIFO 文件不存在时创建它。

如果 FIFO 不存在,您可以通过退出 C 程序来缓解第二个问题,例如:

#include <fcntl.h>
#include <stdio.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>

#define MAX_BUF 1024

int main(int argc, char *argv[])
{
    int fd, i;
    char * myfifo = argv[1];
    char buf[MAX_BUF];

    fd = open(myfifo, O_RDONLY);

    if (fd == -1) {
        perror("opening fifo");
        return 1;
    }
    *buf = '0';
    while (strchr (buf,'x') ==NULL) {
        if((i = read(fd, buf, MAX_BUF)) > 0)
        {
            buf[i] = '\0';
            printf("Received: [%s]\n", buf);
        }
    }

    close(fd);

    return 0;
}

您会注意到我还允许 shell 脚本在通过 x 发送时终止它,并且我还确保缓冲区已正确终止以将其打印为字符串。

对 shell 脚本的(次要)更改是:

#!/bin/bash

fifo_name="myfifo";

# Se non esiste, crea la fifo;
[ -p $fifo_name ] || mkfifo $fifo_name;

echo "3" > $fifo_name;
echo "6" > $fifo_name;
echo "x" > $fifo_name;

然后我在C端看到的输出是:

Received: [3
]
Received: [6
x
]

你会发现它并不总是你所期望的。 read 调用可能会一次接收多个发送,因为顶部没有真正的协议分层。如果您想避免这种情况,您需要添加自己的协议。

【讨论】:

  • 是的..这只是脚本和程序 C 之间的一条路径。但它仍然不能像预期的那样工作:(我希望“收到:3 收到:6”....我取而代之的是“收到:3 6”......这似乎是一件愚蠢的事情,但我认为这意味着我正在一次阅读fifo的内容!它的链接只需要一个循环的循环......我预计至少有 2 个周期......我希望我已经清楚了
  • 事实上,如果我删除了 while 我仍然打印出屏幕,两个写入的值......应该被阻止......不是吗?脚本写一行并阻止某人读取...程序c读取,脚本第二次写入并再次阻塞,程序c读取
  • @Ciccio,查看我的更新,消息中没有固有协议。您可以在每次发送之间敲击sleep 1,但即使这样也不能保证。如果您确定消息将以\n 终止,您应该使用它作为您的协议分隔符。您仍然可能在一次阅读中收到多条(或部分)消息,您只需要自己拆分它们。
猜你喜欢
  • 2014-11-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-01-26
相关资源
最近更新 更多