створити "віртуальний файл" з виводу команди 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. -aПараметр Mutt приймає лише файл, а не потік, але, можливо, є спосіб передати йому якийсь дескриптор віртуального файлу або щось уздовж цих рядків. Щось на зразок:

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

Це можливо? Якщо ні, то чому?

Це, можливо, дурний приклад, і, звичайно, є простіші способи зробити це, але, сподіваюся, це пояснює моє питання щодо створення віртуального файлу з виводу іншої команди.


1
Я не міг заставити <() працювати, поки не зрозумів, що використовую sh замість bash. Це чудово працює. Я підтримаю корисні відповіді, коли (якщо) досягну мінімально необхідної репутації. Дякую за всі відповіді.
П’єр

Відповіді:


53

Це найчистіший спосіб робити те, що ви хочете:

mutt admin@example.org -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" admin@example.org

2
Дивовижно! Я переглядаю таке перенаправлення вперше.
Саураб Барціяя

Дякую за гарне пояснення! Я ніколи цього не бачив ні в яких навчальних посібниках щодо перенаправлення вводу / виводу.
Крістіан Манн

4

Я думаю, що ти шукаєш фіфо, використовуючи 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


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.

Ну добре. Я думаю, що це відповідає на ваше запитання, але з -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 ви використовуєте.

Є також кілька інших альтернатив, включаючи пошту / mailx


1
то це не вкладення, яке, мабуть, буде складніше використовувати для одержувача
freiheit

1
у цьому випадку кращим рішенням буде використання такого інструменту, як metamail (1) або mime-construct (1p), або написання власного, використовуючи щось на зразок модуля perl MIME :: Lite (мій особистий улюблений, тому що це легко робити найпоширеніші речі, пов'язані з мімою).
cas

0

Параметр Mutt -a спеціально використовує типи MIME, визначені в /etc/mime.types. Жоден із типів віртуальних файлів, які, на вашу думку, насправді, не зареєстрований, є зареєстрованим правильним типом mime, тому я не думаю, що вкладення мута може працювати. Тільки для підтвердження концепції, ви можете спробувати встановити пакет підтримки mime (який надає файли доступу до файлів mime, такі як перегляд, редагування тощо) та запустіть see проти віртуального файлу (скажімо, труба), ви побачите, що він робить не визнати. Основна проблема полягає в тому, що зазвичай віртуальний файл зберігає вміст даних у пам'яті, а не на диску, файл-об'єкт - лише вказівник. Ви навіть можете спробувати обернути віртуальний файл з tar / gz і зробити mutt щасливим, але я сумніваюся, що ви отримаєте щось корисне з іншого кінця ... :)

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.