create 'virtual file' da saída do comando bash?

30

Gostaria de saber se existe uma maneira de criar um 'arquivo virtual' a partir de uma saída bash.

Exemplo: Digamos que eu queira enviar por e-mail a saída de mysqldump como um anexo para um endereço de e-mail externo. Eu posso usar o Mutt para fazer isso. A opção mutt que preciso usar é -a <name of the file I want to attach> . Eu sei que eu poderia usar um arquivo temporário:

mysqldump mysqldumpoptions > /tmp/tempfile && mutt -a /tmp/tempfile [email protected]

Mas eu preferiria redirecionar a saída mysqldump diretamente para o Mutt. A opção -a do Mutt só aceita um arquivo e não um fluxo, mas talvez haja uma maneira de passar algum tipo de descritor de arquivo virtual ou algo assim. Algo como:

mutt -a $(mysqldump mysqldumpoptions) [email protected]

É possível? Se não, por quê?

Este talvez seja um exemplo tolo e certamente existem maneiras mais fáceis de fazer isso, mas espero que isso explique minha pergunta sobre a criação de um arquivo virtual a partir da saída de outro comando.

    
por Pierre 14.07.2009 / 07:52

7 respostas

47

Esta é a maneira mais limpa de fazer o que você quer:

mutt [email protected] -a <(mysqldump mysqldumpoptions)

O operador <() é o que você estava pedindo; ele cria um FIFO (ou / dev / fd) e bifurca um processo e conecta o stdout ao FIFO. >() faz o mesmo, exceto conecta stdin ao FIFO. Em outras palavras, ele faz todo o material mknod para você nos bastidores; ou em um sistema operacional moderno, faz isso de uma maneira ainda melhor.

Exceto, claro, que não funciona com o mutt, diz:

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

Eu suspeito que o problema é que o mutt está tentando procurar no arquivo, o que você não pode fazer em um tubo de qualquer tipo. A busca é provavelmente algo como escanear o arquivo para descobrir qual tipo de MIME é e quais codificações podem funcionar (ou seja, se o arquivo é de 7 bits ou 8 bits) e depois buscar o início do arquivo para realmente codificá-lo na mensagem. .

Se o que você deseja enviar é texto sem formatação, sempre é possível fazer algo assim para torná-lo o conteúdo principal do email (não ideal, mas na verdade funciona):

mysqldump mysqldumpoptions | mutt -s "Here's that mysqldump" [email protected]
    
por 14.07.2009 / 08:38
3

Acho que o que você está procurando é um fifo usando mknod

mknod /tmp/foo p

echo hello > /tmp/foo &

cat /tmp/foo

Note que o processo de escrita será bloqueado se não houver processo de leitura.

por exemplo,

mknod /tmp/foo p

mysqldump mysqldumpoptions > /tmp/foo &

mutt -a /tmp/foo
    
por 14.07.2009 / 08:00
1

Precisa ser um anexo? Se ele puder aparecer como o corpo de uma mensagem (ascii limpo de 7 bits, não contém '.' Em uma linha por si só, etc.), então algo assim funcionaria:

mysqldump mysqldumpoptions | mutt -s "today's mysql dump" [email protected]

    
por 14.07.2009 / 08:06
1

Você pode usar o nome do arquivo /dev/stdin com mutt, que lerá de seu stdin.

mysqldump mysqldumpoptions | mutt -a /dev/stdin [email protected]

Hm, eu tentei isso e o mutt reclama:

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

Oh bem. Acho que isso responde à sua pergunta, com a opção -a mutt espera um arquivo regular, o que implica não um dispositivo ou pipe.

    
por 14.07.2009 / 08:09
0

i pode estar faltando alguma coisa aqui, mas por que usar o mutt quando isso soa mais como um trabalho para / usr / sbin / sendmail (ou onde quer que ele esteja na sua distro)?

mysqldump mysqldumpoptions | sendmail [email protected]

a maioria dos MTAs unix fornece um comando / usr / sbin / sendmail, e todos eles entendem mais ou menos as mesmas opções e trabalham mais ou menos da mesma maneira. em quase todos os casos, você não precisa se preocupar com qual MTA / implementação específica do sendmail você está usando.

existem várias outras alternativas também, incluindo mail / mailx

    
por 14.07.2009 / 08:58
0

A opção Mutt-a usa especificamente os tipos MIME definidos em /etc/mime.types. Nenhum dos tipos de arquivos virtuais que você acha que são realmente um tipo mime válido registrado, então eu não acho que o anexo mutt funcionaria. Apenas para a prova do conceito, você pode tentar instalar o pacote mime-support (que fornece binários de acesso a arquivos mime como ver, editar, etc) e rodar ver um arquivo virtual (digamos, um pipe), você verá que não não reconhecê-lo. A questão fundamental é que normalmente um arquivo virtual contém conteúdo de dados na memória, não no disco, o objeto de arquivo é apenas um ponteiro. Você pode até tentar embrulhar um arquivo virtual com tar / gz e deixar o mutt feliz, mas duvido que você consiga algo útil do outro lado ...:)

    
por 14.07.2009 / 09:26
0

Um FIFO é provavelmente o melhor caminho. No entanto, você pode usar mkfifo /path/to/fifo em vez

    
por 23.07.2009 / 17:43