从bash命令输出创build“虚拟文件”?

我想知道是否有办法从bash输出创build一个“虚拟文件”。

示例:假设我想通过电子邮件将mysqldump的输出作为附件发送到外部电子邮件地址。 我可以使用Mutt来做到这一点。 我需要使用的mutt选项是-a <name of the file I want to attach> 。 我知道我可以使用一个临时文件:

 mysqldump mysqldumpoptions > /tmp/tempfile && mutt -a /tmp/tempfile [email protected] 

但是我宁愿将mysqldump输出直接redirect到Mutt。 Mutt的-a选项只接受一个文件,而不是一个stream,但也许有一种方法可以传递某种虚拟文件描述符或者其他的东西。 就像是:

 mutt -a $(mysqldump mysqldumpoptions) [email protected] 

可能吗? 如果没有,为什么?

这可能是一个愚蠢的例子,当然有更简单的方法来做到这一点,但我希望它解释了我从另一个命令的输出创build虚拟文件的问题。

这是做你想做的最干净的方式:

 mutt [email protected] -a <(mysqldump mysqldumpoptions) 

<()运算符是你所要求的; 它会创build一个FIFO(或/ dev / fd)并分叉进程并将stdout连接到FIFO。 >()也是一样的,除了把stdin连接到FIFO。 换句话说,它在幕后为你做了所有的东西。 还是在现代操作系统上,都会以更好的方式来实现。

当然,除此之外,它不适用于mutt,它说:

 /dev/fd/63: unable to attach file. 

我怀疑问题是,mutt试图寻找文件,你不能在任何一种pipe道上进行。 search可能类似于扫描文件以找出它是什么MIMEtypes以及什么编码可能工作(即,文件是7位还是8位),然后寻找文件的开头以将其实际编码到消息中。

如果你想发送的是纯文本,你总是可以做这样的事情,使其成为电子邮件的主要内容,而不是(理想的,但实际上):

 mysqldump mysqldumpoptions | mutt -s "Here's that mysqldump" [email protected] 

我认为你正在寻找的是使用mknod的fifo

 mknod /tmp/foo p echo hello > /tmp/foo & cat /tmp/foo 

请注意,如果没有读取过程,写入过程将会被阻止。

例如

 mknod /tmp/foo p mysqldump mysqldumpoptions > /tmp/foo & mutt -a /tmp/foo 

它需要成为一个附件吗? 如果它可以作为消息的主体出现(7位干净的ascii,它本身不包含'。'),那么类似这样的东西就可以工作:

mysqldump mysqldumpoptions | mutt -s“今天的mysql转储”[email protected]

你可以使用mutt的文件名/dev/stdin ,它会从stdin中读取。

 mysqldump mysqldumpoptions | mutt -a /dev/stdin [email protected] 

嗯,我只是尝试了这个,而且mutt抱怨道:

 /dev/stdin isn't a regular file. /dev/stdin: unable to attach file. 

好吧。 我认为这回答你的问题,但-a选项mutt需要一个常规文件,这意味着不是一个设备或pipe道。

我可能在这里错过了一些东西,但是为什么在这听起来更像是/ usr / sbin / sendmail的工作(或者它在你的发行版上的任何地方)时使用mutt呢?

mysqldump mysqldumpoptions | sendmail [email protected]

大多数unix MTA提供了一个/ usr / sbin / sendmail命令,他们都理解了更多或者更less的相同的选项,并且以相同的方式工作。 在几乎所有的情况下,你都不需要关心你正在使用哪个sendmail的MTA /实现。

还有其他几个select,包括邮件/ mailx

Mutt -a选项专门使用/etc/mime.types中定义的MIMEtypes。 你会认为没有一个虚拟文件types实际上是一个有效的MIMEtypes注册,所以我不认为mutt附件会工作。 只是为了certificate这个概念,你可以尝试安装mime-support软件包(它提供了mime文件访问二进制文件,比如看,编辑等等),并运行一个虚拟文件(比如一个pipe道),你会看到它不承认它。 根本的问题是通常一个虚拟文件在内存中保存数据内容,而不是在磁盘上,文件对象只是一个指针。 你甚至可以尝试用tar / gz包装一个虚拟文件,并使mutt快乐,但是我怀疑你会从另一端得到任何有用的东西… 🙂

FIFO可能是最好的方法。 不过你可以用mkfifo /path/to/fifo代替