créer un «fichier virtuel» à partir de la sortie de la commande bash?

36

Je me demande s’il est possible de créer un «fichier virtuel» à partir d’une sortie bash.

Exemple: supposons que je souhaite envoyer par courrier électronique la sortie de celle-ci en mysqldumptant que pièce jointe à une adresse électronique externe. Je peux utiliser Mutt pour le faire. L' muttoption que je dois utiliser est -a <name of the file I want to attach>. Je sais que je pourrais utiliser un fichier temporaire:

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

Mais je préférerais plutôt rediriger la mysqldumpsortie directement vers Mutt. L' -aoption de Mutt accepte uniquement un fichier et non un flux, mais il existe peut-être un moyen de lui transmettre une sorte de descripteur de fichier virtuel ou quelque chose du genre. Quelque chose comme:

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

C'est possible? Sinon pourquoi?

C’est peut-être un exemple ridicule et il existe sûrement des moyens plus simples de le faire, mais j’espère que cela explique ma question sur la création d’un fichier virtuel à partir de la sortie d’une autre commande.

Pierre
la source
1
Je ne pouvais pas obtenir <() au travail jusqu'à ce que je réalise que j'utilisais sh au lieu de bash. Cela fonctionne très bien. Je vais upvoter les réponses utiles lorsque (si) j'atteins la réputation minimale requise. Merci pour toutes les réponses.
Pierre

Réponses:

53

C'est le moyen le plus propre de faire ce que vous voulez:

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

L' <()opérateur est ce que vous demandiez; il crée une FIFO (ou / dev / fd), lance un processus et connecte la sortie standard à la FIFO. >()fait de même, sauf que connecte stdin à la FIFO à la place. En d’autres termes, il fait tout le travail mknod pour vous dans les coulisses; ou sur un système d'exploitation moderne, le fait d'une manière encore meilleure.

Sauf que, bien sûr, ça ne marche pas avec mutt, ça dit:

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

Je soupçonne que le problème est que Mutt essaye de chercher dans le fichier, ce que vous ne pouvez pas faire sur un tuyau de quelque sorte que ce soit. La recherche est probablement quelque chose comme analyser le fichier pour déterminer son type MIME et quels encodages peuvent fonctionner (c.-à-d. Si le fichier est 7 bits ou 8 bits), puis chercher au début du fichier pour l'encoder réellement dans le message. .

Si ce que vous voulez envoyer est du texte brut, vous pouvez toujours faire quelque chose comme ceci pour en faire le contenu principal de l'e-mail à la place (ce n'est pas idéal, mais cela fonctionne réellement):

mysqldump mysqldumpoptions | mutt -s "Here's that mysqldump" admin@example.org
freiheit
la source
2
Impressionnant! Je vois une telle redirection pour la première fois.
Saurabh Barjatiya
Merci pour la bonne explication! Je n'ai jamais vu cela auparavant, dans aucun tutoriel sur la redirection d'E / S.
Christian Mann
4

Je pense que vous recherchez un fifo utilisant mknod

mknod /tmp/foo p

echo hello > /tmp/foo &

cat /tmp/foo

Notez que le processus d'écriture sera bloqué s'il n'y a pas de processus de lecture.

par exemple

mknod /tmp/foo p

mysqldump mysqldumpoptions > /tmp/foo &

mutt -a /tmp/foo
James
la source
1

Est-ce que cela doit être une pièce jointe? S'il peut apparaître comme le corps d'un message (une ascii vierge de 7 bits, ne contient pas '.' Sur une ligne seule, etc.), quelque chose comme ceci fonctionnerait:

mysqldump mysqldumpoptions | mutt -s "le dump mysql d'aujourd'hui" [email protected]

les pages
la source
1

Vous pourrez peut-être utiliser le nom /dev/stdinde fichier avec mutt, qui sera lu à partir de son stdin.

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

Hm, je viens d'essayer cela et Mutt se plaint:

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

Tant pis. Je pense que cela répond à votre question cependant, avec l' -aoption mutt attend un fichier régulier, ce qui implique pas de périphérique ni de canal.

Greg Hewgill
la source
1

Une FIFO est probablement la meilleure solution. Cependant, vous pouvez utiliser à la mkfifo /path/to/fifoplace

Rory
la source
0

Il se peut que je manque quelque chose ici, mais pourquoi utiliser Mutt alors que cela ressemble plus à un travail pour / usr / sbin / sendmail (ou où que ce soit sur votre distribution)?

mysqldump mysqldumpoptions | sendmail [email protected]

la plupart des MTA unix fournissent une commande / usr / sbin / sendmail, et ils comprennent tous plus ou moins les mêmes options et fonctionnent plus ou moins de la même manière. dans presque tous les cas, vous n'avez pas besoin de vous soucier du MTA / de l'implémentation de sendmail que vous utilisez.

il y a aussi plusieurs autres alternatives, y compris mail / mailx

cas
la source
1
alors ce n'est pas une pièce jointe, qui semble susceptible d'être plus difficile à utiliser pour le destinataire
freiheit
1
dans ce cas, une meilleure solution consisterait à utiliser un outil tel que metamail (1) ou mime-construct (1p) ou à écrire vous-même en utilisant quelque chose comme le module perl MIME :: Lite (mon préféré, car il est facile à faire. les choses les plus courantes liées au mime).
cas
0

L'option Mutt -a utilise spécifiquement les types MIME définis dans /etc/mime.types. Aucun des types de fichiers virtuels que vous penseriez être un type mime valide n’est enregistré, donc je ne pense pas que l'attachement de mutt fonctionnerait. Juste pour la démonstration du concept, vous pouvez essayer d’installer le package mime-support (qui fournit des fichiers binaires d’accès au fichier mime tels que see, edit, etc.) et l’exécuter sur un fichier virtuel (par exemple, un tube). pas le reconnaître. Le problème fondamental est que, normalement, un fichier virtuel conserve le contenu des données en mémoire, et non sur disque, l’objet fichier n’est qu’un pointeur. Vous pouvez même essayer d'envelopper un fichier virtuel avec tar / gz et le rendre heureux, mais je doute que vous obtiendrez quelque chose d'utile de l'autre côté ... :)


la source