我想知道是否有办法从 bash 输出创建“虚拟文件”。
示例:假设我想将 的输出mysqldump
作为附件通过电子邮件发送到外部电子邮件地址。我可以使用 Mutt 来执行此操作。mutt
我需要使用的选项是-a <name of the file I want to attach>
。我知道我可以使用临时文件:
mysqldump mysqldumpoptions > /tmp/tempfile && mutt -a /tmp/tempfile [email protected]
但我宁愿将mysqldump
输出直接重定向到 Mutt。Mutt 的-a
选项只接受文件而不是流,但也许有办法向其传递某种虚拟文件描述符或类似的东西。例如:
mutt -a $(mysqldump mysqldumpoptions) [email protected]
有可能吗?如果不可能,为什么?
这可能是一个愚蠢的例子,并且肯定有更简单的方法可以做到这一点,但我希望它能解释我关于从另一个命令的输出创建虚拟文件的问题。
答案1
这是做你想做的事情最干净的方法:
mutt [email protected] -a <(mysqldump mysqldumpoptions)
操作<()
符就是您要求的;它创建一个 FIFO(或 /dev/fd)并派生一个进程,并将 stdout 连接到 FIFO。 >()
执行相同操作,但将 stdin 连接到 FIFO。换句话说,它在后台为您完成所有 mknod 操作;或者在现代操作系统上,以更好的方式完成它。
当然,这对 mutt 不起作用,它说:
/dev/fd/63: unable to attach file.
我怀疑问题在于 mutt 试图在文件中进行搜索,而您无法在任何类型的管道上进行搜索。搜索可能类似于扫描文件以确定其 MIME 类型以及哪些编码可能有效(即文件是 7 位还是 8 位),然后搜索到文件的开头以将其实际编码到消息中。
如果您想要发送的是纯文本,您可以采取如下方式使其成为电子邮件的主要内容(虽然不理想,但确实有效):
mysqldump mysqldumpoptions | mutt -s "Here's that mysqldump" [email protected]
答案2
我认为你正在寻找的是使用 fifomknod
mknod /tmp/foo p
echo hello > /tmp/foo &
cat /tmp/foo
注意,如果没有读取过程,则写入过程将会阻塞。
例如
mknod /tmp/foo p
mysqldump mysqldumpoptions > /tmp/foo &
mutt -a /tmp/foo
答案3
FIFO 可能是最好的方法。不过你也可以mkfifo /path/to/fifo
使用
答案4
您可能能够将文件名/dev/stdin
与 mutt 一起使用,它将从其标准输入中读取。
mysqldump mysqldumpoptions | mutt -a /dev/stdin [email protected]
嗯,我刚刚尝试了一下,mutt 抱怨道:
/dev/stdin isn't a regular file.
/dev/stdin: unable to attach file.
好吧。不过我认为这回答了你的问题,因为-a
mutt 需要一个常规文件,这意味着不是一个设备或管道。