我有一个二进制程序*,它获取提供的文件的内容,处理它,并通过stdout在屏幕上打印结果。对于自动化脚本,我想使用命名管道将数据发送到此程序并自行处理输出。在尝试使脚本工作之后,我意识到二进制程序接受来自命名管道的数据存在问题。为了说明这个问题,我已经使用unix shell概述了几个测试。
通过处理实际数据文件很容易显示程序正常工作。
$ binprog file.txt > output.txt
这将导致output.txt包含来自file.txt的处理过的信息。
命名管道(pipe.txt)的工作方式如此演示所示。
$ cat pipe.txt > output.txt
$ cat file.txt > pipe.txt
这将导致output.txt在通过管道发送后包含来自file.txt的数据。
当二进制程序从命名管道而不是文件读取时,事情无法正常工作。
$ binprog pipe.txt > output.txt
$ cat file.txt > pipe.txt
在这种情况下,即使cat和binprog终止,output.txt也不包含任何数据。使用top和ps,我可以看到binprog“正在运行”并且看似正在工作。一切都没有错误地执行。
为什么在第三个例子中没有binprog产生的输出?
有什么东西我可以试着让它起作用吗?
[*]有问题的程序是来自libsvm的svm-scale。我选择概括这些例子以保持它们简洁明了。
答案 0 :(得分:3)
您确定程序可以使用管道吗?如果它需要随机访问输入文件,它将无法正常工作。每当尝试在输入文件中搜索时,程序都会收到错误。
如果您知道该程序旨在使用管道,并且您正在使用bash,则可以使用进程替换来避免必须显式创建命名管道。
binprog <(cat file.txt) > output.txt
答案 1 :(得分:1)
binprog是否也接受stdin的输入?如果是这样,这可能适合你。
cat pipe.txt | binprog > output.txt
cat file.txt > pipe.txt
编辑:简要扫描了svm-scale的联机帮助页。给这个旋转一下:
cat pipe.txt | svm-scale - > output.txt
答案 2 :(得分:0)
如果binprog
与终端之外的任何其他设备都不能正常工作,那么您可能需要为其输入提供一个(伪)终端(pty)。这很难组织,但expect
程序是相对容易做到这一点的一种方式。有关于pty的编程的讨论
W Richard Stevens和Stephen A Rago的Advanced Programming in the Unix Environment, 3rd Edn,以及Marc J Rochkind的Advanced Unix Programming, 2nd Edn。
要查看的其他内容是truss
或strace
或本地等效项的输出。这些程序记录进程所做的所有系统调用。在Solaris上,我运行:
truss -o binprog.truss binprog
以交互方式,看看它的作用。然后我尝试使用i / o重定向,然后使用命名管道的i / o重定向;它的作用可能会有一些显着的差异,或者您可能会看到挂起的系统调用。如果您在桁架日志文件中看到分叉,则需要添加“-f
”标记来跟踪孩子。