criar 'arquivo virtual' a partir da saída do comando bash?

36

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

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

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

Mas prefiro redirecionar a mysqldumpsaída diretamente para o Mutt. A -aopção de Mutt aceita apenas um arquivo e não um fluxo, mas talvez haja uma maneira de transmitir algum tipo de descritor de arquivo virtual ou algo nesse sentido. Algo como:

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

É possível? Se não, por que?

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

Pierre
fonte
1
Não consegui <() trabalhar até perceber que estava usando sh em vez de bash. Está funcionando muito bem. Promoverei as respostas úteis quando (se) atingir a reputação mínima necessária. Obrigado por todas as respostas.
Pierre

Respostas:

53

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

mutt admin@example.org -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 que conecta stdin ao FIFO. Em outras palavras, ele faz todo o material necessário 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 vira-lata, 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 nenhum tipo de canal. A busca é provavelmente algo como varrer o arquivo para descobrir qual é o tipo MIME e quais codificações podem funcionar (ou seja, se o arquivo é 7 bits ou 8 bits) e, em seguida, procurar no início do arquivo codificá-lo de fato na mensagem .

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

mysqldump mysqldumpoptions | mutt -s "Here's that mysqldump" admin@example.org
freiheit
fonte
2
Impressionante! Estou vendo esse redirecionamento pela primeira vez.
Saurabh Barjatiya
Obrigado pela boa explicação! Eu nunca vi isso antes, em nenhum tutorial sobre redirecionamento de E / S.
Christian Mann
4

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

mknod /tmp/foo p

echo hello > /tmp/foo &

cat /tmp/foo

Observe que o processo de gravação será bloqueado se não houver um processo de leitura.

por exemplo

mknod /tmp/foo p

mysqldump mysqldumpoptions > /tmp/foo &

mutt -a /tmp/foo
James
fonte
1

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

mysqldumpopções mysqldump | mutt -s "despejo de mysql de hoje" [email protected]

pgs
fonte
1

Você pode usar o nome do arquivo /dev/stdincom o mutt, que será lido a partir do stdin.

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

Hm, eu apenas tentei isso e vira-lata reclama:

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

Ah bem. Eu acho que isso responde à sua pergunta, porém, com a -aopção mutt espera um arquivo regular, o que não implica em um dispositivo ou canal.

Greg Hewgill
fonte
1

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

Rory
fonte
0

posso estar faltando alguma coisa aqui, mas por que usar o mutt quando isso parece mais um trabalho para / usr / sbin / sendmail (ou onde quer que esteja na sua distribuição)?

mysqldumpopções mysqldump | sendmail [email protected]

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

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

cas
fonte
1
então não é um anexo, o que parece provável que seja mais difícil de usar para o destinatário
Freiheit
1
nesse caso, uma solução melhor seria usar uma ferramenta como metamail (1) ou mime-construct (1p) ou escrever sua própria usando algo como o módulo perl MIME :: Lite (meu favorito pessoal porque facilita a execução as coisas mais comuns relacionadas à mímica).
14285
0

A opção Mutt -a usa especificamente os tipos MIME definidos em /etc/mime.types. Nenhum dos tipos de arquivo virtual que você acha que é 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 executar see em um arquivo virtual (por exemplo, um pipe), você verá que sim não reconhecê-lo. A questão fundamental é que normalmente um arquivo virtual mantém o conteúdo dos dados na memória, não no disco, o objeto do arquivo é apenas um ponteiro. Você pode até tentar quebrar um arquivo virtual com tar / gz e deixar o vira-lata feliz, mas duvido que você obtenha algo útil do outro lado ... :)


fonte