Интересно, есть ли способ создать «виртуальный файл» из вывода 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
Я думаю, что вы ищете 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
решение3
FIFO, вероятно, является лучшим способом. Однако вы можете использовать mkfifo /path/to/fifo
вместо этого
решение4
Вы можете использовать имя файла /dev/stdin
с Mutt, который будет считывать данные со своего stdin.
mysqldump mysqldumpoptions | mutt -a /dev/stdin [email protected]
Хм, я только что попробовал это, и мутт жалуется:
/dev/stdin isn't a regular file.
/dev/stdin: unable to attach file.
Ну что ж. Я думаю, что это ответ на ваш вопрос, хотя с -a
опцией mutt ожидает обычный файл, что подразумевает не устройство или канал.