crear 'archivo virtual' desde la salida del comando bash?

36

Me pregunto si hay una manera de crear un 'archivo virtual' a partir de una salida bash.

Ejemplo: supongamos que quiero enviar por correo electrónico la salida de mysqldumpun archivo adjunto a una dirección de correo electrónico externa. Puedo usar Mutt para hacerlo. La muttopción que necesito usar es -a <name of the file I want to attach>. Sé que podría usar un archivo temporal:

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

Pero prefiero redirigir la mysqldumpsalida directamente a Mutt. La -aopción de Mutt solo acepta un archivo y no una secuencia, pero tal vez haya una forma de pasarle algún tipo de descriptor de archivo virtual o algo por el estilo. Algo como:

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

¿Es posible? Si no, ¿por qué?

Este es quizás un ejemplo tonto y seguramente hay formas más fáciles de hacerlo, pero espero que explique mi pregunta sobre la creación de un archivo virtual a partir de la salida de otro comando.

Pierre
fuente
1
No pude hacer que <() funcionara hasta que me di cuenta de que estaba usando sh en lugar de bash. Funciona muy bien Votaré las respuestas útiles cuando (si) alcance la reputación mínima necesaria. Gracias por todas las respuestas.
Pierre

Respuestas:

53

Esta es la forma más limpia de hacer lo que quieres:

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

El <()operador es lo que estabas pidiendo; crea un FIFO (o / dev / fd) y bifurca un proceso y conecta stdout al FIFO. >()hace lo mismo, excepto que conecta stdin al FIFO en su lugar. En otras palabras, hace todo lo necesario para usted detrás de escena; o en un sistema operativo moderno, lo hace de una manera aún mejor.

Excepto, por supuesto, que no funciona con mutt, dice:

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

Sospecho que el problema es que mutt está tratando de buscar en el archivo, lo que no se puede hacer en una tubería de ningún tipo. La búsqueda es probablemente algo así como escanear el archivo para descubrir qué tipo de MIME es y qué codificaciones podrían funcionar (es decir, si el archivo es de 7 bits u 8 bits), y luego buscar el comienzo del archivo para codificarlo realmente en el mensaje .

Si lo que desea enviar es texto sin formato, siempre puede hacer algo como esto para convertirlo en el contenido principal del correo electrónico (no es ideal, pero en realidad funciona):

mysqldump mysqldumpoptions | mutt -s "Here's that mysqldump" admin@example.org
freiheit
fuente
2
¡Increíble! Estoy viendo esa redirección por primera vez.
Saurabh Barjatiya
¡Gracias por la buena explicación! Nunca he visto esto antes, en ningún tutorial sobre redirección de E / S.
Christian Mann
4

Creo que lo que estás buscando es un quince usando mknod

mknod /tmp/foo p

echo hello > /tmp/foo &

cat /tmp/foo

Tenga en cuenta que el proceso de escritura se bloqueará si no hay un proceso de lectura.

p.ej

mknod /tmp/foo p

mysqldump mysqldumpoptions > /tmp/foo &

mutt -a /tmp/foo
James
fuente
1

¿Tiene que ser un archivo adjunto? Si puede aparecer como el cuerpo de un mensaje (ascii limpio de 7 bits, no contiene '.' En una línea por sí mismo, etc.), entonces algo como esto funcionaría:

mysqldump mysqldumpoptions | mutt -s "el volcado de MySQL de hoy" [email protected]

pgs
fuente
1

Es posible que pueda usar el nombre de archivo /dev/stdincon mutt, que se leerá en su stdin.

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

Hm, acabo de intentar esto y mutt se queja:

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

Oh bien. Sin embargo, creo que esto responde a su pregunta, con la -aopción mutt espera un archivo normal, lo que implica no un dispositivo o tubería.

Greg Hewgill
fuente
1

Un FIFO es probablemente la mejor manera. Sin embargo, puedes usar mkfifo /path/to/fifoen su lugar

Rory
fuente
0

Puede que me falte algo aquí, pero ¿por qué usar mutt cuando esto suena más como un trabajo para / usr / sbin / sendmail (o donde sea que viva en su distribución)?

mysqldump mysqldumpoptions | sendmail [email protected]

La mayoría de los MTA de Unix proporcionan un comando / usr / sbin / sendmail, y todos entienden más o menos las mismas opciones y trabajan más o menos de la misma manera. en casi todos los casos, no necesita preocuparse qué MTA / implementación particular de sendmail está utilizando.

También hay varias otras alternativas, incluyendo mail / mailx

cas
fuente
1
entonces no es un archivo adjunto, lo que parece probable que sea más difícil de usar para el destinatario
Freiheit
1
en ese caso, una mejor solución sería usar una herramienta como metamail (1) o mime-construct (1p) o escribir la suya usando algo como el módulo perl MIME :: Lite (mi favorito personal porque lo hace fácil de hacer las cosas más comunes relacionadas con el mimo).
cas
0

La opción Mutt -a utiliza específicamente los tipos MIME definidos en /etc/mime.types. Ninguno de los tipos de archivos virtuales que crees que es realmente un tipo mime válido registrado, por lo que no creo que el adjunto mutt funcione. Solo como prueba del concepto, puede intentar instalar el paquete mime-support (que proporciona binarios de acceso a archivos mime como see, edit, etc.) y ejecutar see contra un archivo virtual (digamos una tubería), verá que lo hace No lo reconozco. El problema fundamental es que normalmente un archivo virtual contiene contenido de datos en la memoria, no en el disco, el objeto del archivo es solo un puntero. Incluso puede intentar envolver un archivo virtual con tar / gz y hacer que mutt esté feliz, pero dudo que obtenga algo útil del otro extremo ... :)


fuente