我有一些任意数据作为命令的输出(例如使用输出的二进制数据的片段tail
)。我想将它提供给另一个命令/程序,该命令/程序只允许一个文件作为参数(例如rawtopng [filein] [fileout]
),不支持破折号(-
)参数,并且我无法在两者之间创建临时文件。我怎样才能在 bash 中做到这一点?
会做类似rawtopng <(tail myfile) fileout
工作的事情吗?
答案1
进程替换rawtopng <(tail myfile) fileout
创建一个管道(就像tail myfile | rawtopng - fileout
),并将管道的名称传递给程序。在 Linux 上,rawtopng
会看到类似 的名称/dev/fd/42
,如果它查询文件类型,则会被告知它是一个管道。不需要写入文件系统(这是匿名管道,而不是命名管道)。您可以通过运行如下命令来了解正在发生的情况ls -ld <(echo foo)
这行得通吗?这取决于rawtopng
命令需要什么(我不知道,我不熟悉该命令)。如果它所做的只是从文件中读取,那就没问题。如果它需要在文件中查找(即,如果它没有从头到尾线性地读取输入),或者如果它需要在开始工作之前知道输入的大小,那么这是行不通的。在这种情况下,您将需要一个临时文件。
如果命令需要可查找的输入或预先知道大小的输入,那么您别无选择,您需要创建一个临时文件。如果您想避免写入磁盘,您可以安排将文件放在tmpfs
文件系统上,如果您的 Unix 变体提供了该功能(Linux 提供了)。您可以使用以下mktemp
命令创建临时文件:
tmp=$(TMPDIR=/tmp mktemp XXXXXXXXXXXX.raw)
rawtopng "$tmp" fileout
rm "$tmp"
在 zsh 中,进程替换变体会rawtopng =(tail myfile) fileout
创建一个临时文件,并在命令完成后将其删除。
进程替换无法解决的另一种情况是,如果程序坚持使用具有特定扩展名的文件。在这种情况下,创建命名管道可能会有所帮助:
mkfifo /tmp/foo.raw
tail myfile >/tmp/foo.raw &
rawtopng /tmp/foo.raw fileout
rm /tmp/foo.raw
答案2
答案3
您可以创建命名管道。
做一些类似mkfifo input
创建管道的事情。
启动您想要读取输出的程序,并将输出重定向到管道,又名myprog > input
然后使用输入作为文件运行其他命令。
请注意,管道是单向的。该程序将能够读取,但不能写入。