0

我有一个二进制程序*,它获取所提供文件的内容,对其进行处理,并通过标准输出在屏幕上打印结果。对于自动化脚本,我想使用命名管道将数据发送到该程序并自己处理输出。在尝试让脚本工作后,我意识到二进制程序从命名管道接受数据存在问题。为了说明这个问题,我概述了几个使用 unix shell 的测试。

  1. 很容易证明程序通过处理实际数据文件来工作。

    $ binprog file.txt > output.txt
    

    这将导致 output.txt 包含来自 file.txt 的已处理信息。

  2. 如本演示所示,命名管道 (pipe.txt) 的工作原理。

    $ cat pipe.txt > output.txt
    $ cat file.txt > pipe.txt
    

    这将导致 output.txt 在通过管道发送后包含来自 file.txt 的数据。

  3. 当二进制程序从命名管道而不是文件读取时,事情不能正常工作。

    $ binprog pipe.txt > output.txt
    $ cat file.txt > pipe.txt
    

    在这种情况下,即使 cat 和 binprog 终止, output.txt 也不包含任何数据。使用 top 和 ps,我可以看到 binprog “运行”并且似乎在工作。一切都执行没有错误。

为什么在第三个示例中 binprog 没有输出?

我可以尝试哪些事情来使它正常工作?

[*] 有问题的程序是来自libsvm的 svm-scale 。我选择概括示例以保持它们的简洁。

4

3 回答 3

3

您确定该程序可以使用管道吗?如果它需要随机访问输入文件,它将无法工作。每当程序尝试在输入文件中查找时,都会出错。

如果您知道该程序旨在使用管道,并且您正在使用 bash,则可以使用进程替换来避免必须显式创建命名管道。

binprog <(cat file.txt) > output.txt
于 2009-03-20T01:48:42.633 回答
1

binprog 是否也接受标准输入上的输入?如果是这样,这可能对你有用。

cat pipe.txt | binprog > output.txt
cat file.txt > pipe.txt

编辑:简要扫描了 svm-scale 的联机帮助页。试一试:

cat pipe.txt | svm-scale - > output.txt
于 2009-03-20T01:38:40.333 回答
0

如果binprog除了终端作为输入之外的任何东西都不能很好地工作,也许你需要给它一个(伪)终端(pty)作为它的输入。这更难组织,但该expect程序是相对容易地做到这一点的一种方式。W Richard Stevens 和 Stephen A Rago的Advanced Programming in the Unix Env​​ironment, 3rd Edn和Marc J Rochkind的Advanced Unix Programming, 2nd Edn中讨论了使用 pty 进行 编程。

要查看的其他内容是trussorstrace或本地等效项的输出。这些程序记录一个进程进行的所有系统调用。在 Solaris 上,我会运行:

truss -o binprog.truss binprog

交互式地,看看它做了什么。然后我会尝试使用 i/o 重定向,然后使用来自命名管道的 i/o 重定向;它的作用可能存在一些显着差异,或者您可能会看到挂起的系统调用。如果您在 truss 日志文件中看到分叉,则需要添加一个 ' -f' 标志来跟随子级。

于 2009-03-20T03:16:17.557 回答