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


36

我想知道是否有一种方法可以从bash输出中创建“虚拟文件”。

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

mysqldump mysqldumpoptions > /tmp/tempfile && mutt -a /tmp/tempfile admin@example.org

但是我宁愿将mysqldump输出直接重定向到Mutt。Mutt的-a选项仅接受文件,而不接受流,但是也许有一种方法可以传递某种虚拟文件描述符或类似的东西。就像是:

mutt -a $(mysqldump mysqldumpoptions) admin@example.org

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

这可能是一个愚蠢的示例,并且肯定有更简单的方法来执行此操作,但是我希望它能解释我有关从另一个命令的输出创建虚拟文件的问题。


1
在意识到使用sh而不是bash之前,我无法让<()工作。运行良好。当(如果)达到所需的最低声誉时,我将对有用的答复进行投票。感谢您的所有答复。
Pierre

Answers:


53

这是您想要做的最干净的方法:

mutt admin@example.org -a <(mysqldump mysqldumpoptions)

<()操作是你问什么; 它创建一个FIFO(或/ dev / fd)并派生一个进程并将stdout连接到FIFO。 >()除了将stdin连接到FIFO之外,其他功能相同。换句话说,它在幕后为您完成了所有mknod任务;或在现代OS上以更好的方式进行操作。

它当然说,除了不适用于mutt以外,它说:

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

我怀疑问题是mutt试图在文件中查找,而您无法在任何类型的管道上执行该操作。搜索可能类似于扫描文件以确定其MIME类型以及可能的编码方式(即文件是7位还是8位),然后搜索文件的开头以将其实际编码为消息。 。

如果您要发送的是纯文本,则可以始终执行以下操作以使其成为电子邮件的主要内容(虽然不理想,但实际上可以工作):

mysqldump mysqldumpoptions | mutt -s "Here's that mysqldump" admin@example.org

2
太棒了!我是第一次看到这种重定向。
Saurabh Barjatiya 09年

谢谢您的解释!在任何有关I / O重定向的教程中,我从未见过。
Christian Mann

4

我认为您正在寻找的是FIFO使用 mknod

mknod /tmp/foo p

echo hello > /tmp/foo &

cat /tmp/foo

请注意,如果没有读取过程,则写入过程将阻塞。

例如

mknod /tmp/foo p

mysqldump mysqldumpoptions > /tmp/foo &

mutt -a /tmp/foo

1

需要附件吗?如果它可以显示为消息的正文(7位纯净ascii,本身在一行中不包含“。”等),那么类似的方法将起作用:

mysqldump mysqldump选项| mutt -s“今天的mysql dump” admin@example.org


1

您也许可以将文件名/dev/stdin与mutt 一起使用,该文件名将从其stdin中读取。

mysqldump mysqldumpoptions | mutt -a /dev/stdin admin@example.org

嗯,我只是试过了,笨蛋抱怨道:

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

那好吧。我认为这可以回答您的问题,但是-amutt选项需要一个常规文件,这意味着没有设备或管道。


1

FIFO可能是最好的方法。但是您可以mkfifo /path/to/fifo改用


0

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

mysqldump mysqldump选项| sendmail admin@example.org

大多数Unix MTA提供/ usr / sbin / sendmail命令,它们都或多或少地理解相同的选项,并以或多或少地相同的方式工作。在几乎所有情况下,您都无需关心所使用的特定MTA / sendmail实现。

还有其他几种选择,包括mail / mailx


1
那么它是不是一个附件,这很可能是更难使用收件人
自由报

1
在这种情况下,更好的解决方案是使用诸如metamail(1)或mime-construct(1p)之类的工具,或者使用诸如perl MIME :: Lite模块之类的东西编写自己的工具(我个人最喜欢这样做,因为它使操作变得容易最常见的与哑剧有关的事物)。
cas

0

Mutt -a选项专门使用在/etc/mime.types中定义的MIME类型。您不会认为实际上已注册的有效mime类型中的任何虚拟文件类型,因此我认为Mutt附件不起作用。只是为了证明这一概念,您可以尝试安装mime-support软件包(它提供mime文件访问二进制文件,例如see,edit等)并针对虚拟文件(例如管道)运行see,您将看到它确实不认识它。根本问题是虚拟文件通常将数据内容保存在内存中,而不是磁盘中,文件对象只是一个指针。您甚至可以尝试用tar / gz包装一个虚拟文件并使mutt满意,但我怀疑您会从另一端得到任何有用的信息... :)

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.