【问题标题】:Sending a command to a running process using a named pipe使用命名管道向正在运行的进程发送命令
【发布时间】:2012-12-30 20:09:42
【问题描述】:

我有一个作为服务运行的程序,它从控制台获取标准输入,并将反馈打印到屏幕上。可以认为是下面这个简单的例子,而printf()函数实际上是一个更复杂的函数。

//keyin.c
int main(int argc, char *argv[])
{
    char buf[80];
    int i = 1;

    while(i++){ 
    printf("enter %d string: \n", i);
    scanf("%s", buf);
    printf("print %d string: %s \n\n", i, buf);
    sleep(2);
    }

    return 0;
}

现在我想使用命名管道作为输入,这样我就可以使用另一个程序通过写入管道来将所需的命令传递给服务,而不是在控制台中输入。

我创建了一个命名管道:

mknod MYFIFO p

然后我通过以下方式重定向输入:

root@ubuntu: ./keyin < MYFIFO

然后我将命令写入管道:

root@ubuntu: echo "test" > MYFIFO

我希望服务接受“测试”,将其打印出来,然后等待下一个输入,但是,在第一次运行之后,它会无限地打印出“测试”,并且再也不会响应管道文件,甚至当我删除它时。

我做错了什么?

【问题讨论】:

    标签: c named-pipes


    【解决方案1】:

    您应该检查scanf() 的返回值。请注意,每次获得相同的重复缓冲区时,scanf() 都会返回一个负值。

    int main(int argc, char *argv[]){
       char buf[80];
       int i = 1;
           while(i++){
           if(scanf("%s", buf) > 0){
               printf("print %d string: %s \n\n", i, buf);
           }
           sleep(2);
        }
        return 0;
    }
    

    另外,请注意,命名管道与普通管道或控制台不同,表现不同。

    【讨论】:

    • 感谢您的回答。您的解决方案在这种 scanf/printf 情况下确实有效,但 while() 循环继续运行。我的真实程序比简单的 scanf() 复杂得多,因此我无法做到这一点。我希望有一个解决方案可以让程序挂在那里,直到发出下一个命令。除了名称管道,您还有其他解决方案吗?假设我只有一个二进制可执行文件 test.exe,它接受键盘输入并相应地执行一些操作。现在我想让 test.exe 作为服务在后台运行,并使用另一个程序将命令传递给 test.exe,我该怎么做?
    • 谢谢,我想我知道问题出在哪里了。命名管道需要连接到写入器和读取器。在 echo "test">MYPIPE 的情况下,管道文件在 echo 后被关闭,因此 reader 得到一个 EOF,然后进入无限循环。而不是使用“keyin
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-19
    相关资源
    最近更新 更多