如何通过管道传输只能写入文件(而不能写入 STDOUT)的程序的输出?
我正在尝试编写类似 Perl Audio Converter 的内容,因此我需要能够解码每个相关的音频格式为 wav (PCM),然后将 wav 编码为每种相关的音频格式。我想通过将解码器的输出直接传输到编码器的输入来并行执行此操作。大多数解码器都可以选择解码到标准输出,但并非所有解码器都可以。有些坚持输出到文件。
所以我的问题是,如何欺骗仅输出到指定文件的程序使用 stdout 来代替?另外,补充问题:如何欺骗需要输入文件的程序从标准输入读取?
这是否不可能,因为程序可能想要在输出中来回查找?
顺便说一句,Perl Audio Converter 通过始终使用中间 wav 文件来回避这个问题,这意味着它永远不会并行进行解码和编码,即使对于支持它的格式也是如此。
PS:是的,我不想只使用 Perl Audio Converter 是有原因的,但这与问题无关。
I'm trying to write something like Perl Audio Converter, so I need to be able to decode every relevant audio format to wav (PCM) and then encode wav to every relevant audio format. I'd like to do this in parallel, by piping the output of the decoder directly to the input of the encoder. Most decoders have an option to decode to stdout, but not all of them do. Some insist on outputting to a file.
So my question is, how can I trick a program that will only output to a specified file into using stdout instead? Also, the complementary question: how can I trick a program that requires in input file into reading from stdin?
Would this be impossible because the program might want to seek back and forth within the output?
Incidentally, Perl Audio Converter sidesteps this problem by always using an intermediate wav file, which means that it never does decoding and encoding in parallel, even for formats that support it.
PS: Yes, there's a reason I don't want to just use Perl Audio Converter, but it's not relevant to the question.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
在 Linux 上,您可以将
/proc/self/fd/1
作为“文件”输出。这应该适用于任何不尝试在输出中查找的程序。
有些程序确实会在输出中进行查找(例如,解码完成后在文件开头写入摘要信息),并且对于除真实文件之外的任何文件,此查找都会失败。
如果程序检查
fseek
或lseek
的返回值(理应如此),则程序可能会返回错误。如果没有,它可能会成功退出,但会产生错误的输出(例如,开头的摘要信息不正确,结尾有额外的“垃圾”)。On Linux, you can give
/proc/self/fd/1
as a "file" output.That should work for any program that doesn't try to seek in the output.
Some programs do seek in output (e.g. to write summary info at the start of the file once decoding is complete), and this seek will fail with anything other than a real file.
If the program checks the return value of
fseek
orlseek
(as it should), the program will likely return an error. If it doesn't, it will likely exit successfully, but will create erroneous output (e.g. with incorrect summary info in the beginning, and extra "junk" at the end).某些操作系统(例如 Unix 变体和 win32 系列)支持命名管道。您也许可以使用它们来代替 stdout/stdin。
Some OSes, such as Unix variants and the win32 family, support named pipes. You might be able to use them instead of stdout/stdin.
制作一个命名管道。
而不是执行例如
您可以将其用作文件,
(无论先启动哪个都会阻塞,直到管道的另一端打开)
但你是对的,如果程序确实需要一个实际的文件来进行搜索,那么这将不起作用。
Make a named pipe.
Instead of doing e.g.
you can use it as a file
(whichever is started first will block until the other end of the pipe is opened)
But you're right, if the program does require an actual file for e.g. seeking, this will not work.
创建管道并将输出分配给管道
Create a pipe and assign output to the pipe