создать «виртуальный файл» из вывода команды bash?

36

Интересно, есть ли способ создать «виртуальный файл» из результатов bash?

Пример: допустим, я хочу отправить вывод по электронной почте в mysqldumpвиде вложения на внешний адрес электронной почты. Я могу использовать Матта, чтобы сделать это. muttВариант мне нужно использовать это -a <name of the file I want to attach>. Я знаю, что могу использовать временный файл:

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

Но я бы предпочел вместо этого перенаправить mysqldumpвывод непосредственно в Mutt. -aОпция Mutt принимает только файл, а не поток, но, возможно, есть способ передать ему какой-то виртуальный дескриптор файла или что-то в этом роде. Что-то типа:

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

Является ли это возможным? Если нет, то почему?

Это, возможно, глупый пример, и, конечно, есть более простые способы сделать это, но я надеюсь, что это объясняет мой вопрос о создании виртуального файла из вывода другой команды.

пьер
источник
1
Я не мог заставить <() работать, пока не понял, что использую sh вместо bash. Работает отлично. Я буду приветствовать полезные ответы, когда (если) достигну минимально необходимой репутации. Спасибо за все ответы.
Пьер

Ответы:

53

Это самый чистый способ сделать то, что вы хотите:

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

<()Оператор, что вы просили; он создает FIFO (или / dev / fd), разветвляет процесс и подключает стандартный вывод к FIFO. >()делает то же самое, за исключением того, что вместо этого соединяет стандартный ввод с FIFO. Другими словами, он делает все, что вам нужно, за кулисами; или на современной ОС, делает это еще лучше.

За исключением, конечно, что это не работает с Mutt, он говорит:

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

Я подозреваю, что проблема в том, что Mutt пытается найти файл, чего нельзя сделать на каком-либо канале. Поиск - это, вероятно, что-то вроде сканирования файла, чтобы выяснить, какой это тип MIME и какие кодировки могут работать (т. Е. Является ли файл 7-битным или 8-битным), а затем поиск в начале файла для фактического кодирования его в сообщение. ,

Если вы хотите отправить простой текст, вы всегда можете сделать что-то вроде этого, чтобы сделать его основным содержимым письма (не идеально, но на самом деле это работает):

mysqldump mysqldumpoptions | mutt -s "Here's that mysqldump" admin@example.org
Freiheit
источник
2
Потрясающе! Я вижу такое перенаправление впервые.
Саураб Баржатия
Спасибо за хорошее объяснение! Я никогда не видел этого раньше, ни в одном руководстве по перенаправлению ввода / вывода.
Кристиан Манн
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 mysqldumpoptions | mutt -s "сегодняшний дамп mysql" admin@example.org

PGS
источник
1

Вы можете использовать имя файла /dev/stdinс Mutt, который будет читать из его стандартного ввода.

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

Хм, я только что попробовал это и дурак жалуется:

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

Ну что ж. Я думаю, что это отвечает на ваш вопрос, хотя, с -aопцией Mutt ожидает обычный файл, который подразумевает не устройство или канал.

Грег Хьюгилл
источник
1

FIFO, наверное, лучший способ. Однако вы можете использовать mkfifo /path/to/fifoвместо

Рори
источник
0

Возможно, я что-то здесь упускаю, но зачем использовать Mutt, когда это больше похоже на работу для / usr / sbin / sendmail (или там, где он живет в вашем дистрибутиве)?

mysqldump mysqldumpoptions | sendmail admin@example.org

большинство Unix MTA предоставляют команду / usr / sbin / sendmail, и все они более или менее понимают одни и те же опции и работают более или менее одинаково. почти во всех случаях вам не нужно заботиться о том, какую конкретную MTA / реализацию sendmail вы используете.

Есть также несколько других альтернатив, в том числе mail / mailx

саз
источник
1
тогда это не вложение, которое, вероятно, будет сложнее использовать получателю
freiheit
1
в этом случае лучшим решением будет использование такого инструмента, как metamail (1) или mime-construct (1p), или создание собственного с использованием чего-то вроде модуля perl MIME :: Lite (мой личный фаворит, потому что это легко сделать). самые распространенные вещи, связанные с пантомимой).
Cas
0

Параметр Mutt -a специально использует типы MIME, определенные в /etc/mime.types. Ни один из виртуальных типов файлов, которые, на ваш взгляд, на самом деле не являются зарегистрированными действительными типами MIME, поэтому я не думаю, что вложение Mutt не будет работать. Просто для подтверждения концепции, вы можете попробовать установить пакет поддержки mime (который обеспечивает двоичные файлы доступа к файлам mime, такие как просмотр, редактирование и т. Д.) И запустить see для виртуального файла (скажем, канала), вы увидите, что он делает не признать это. Основная проблема заключается в том, что обычно виртуальный файл хранит данные в памяти, а не на диске, объект файла - это просто указатель. Вы даже можете попробовать обернуть виртуальный файл с помощью tar / gz и сделать Mutt счастливым, но я сомневаюсь, что вы получите что-нибудь полезное с другого конца ... :)


источник