construção de pipe bash para acrescentar algo à saída padrão do comando anterior

25

Quero usar o sendmail para me enviar coisas e quero fazê-lo em um oneliner.

echo "mail content" | sendmail emailataddres.com 

Envia sem assunto.

A linha de assunto deve vir antes do conteúdo do Mail, então estou procurando algo ao longo das linhas de:

echo "mail content" | prepend "Subject: All that matters" | sendmail emailataddres.com 

sed e awk tendem a ser realmente difíceis de usar e lembrar.

EDIT : Apenas para esclarecer: echo "Conteúdo de email" é apenas um exemplo ilustrativo. Eu preciso ser capaz de acrescentar coisas aos fluxos stdout de qualquer fonte. por exemplo: ifconfig, zcat, etc.

AndreasT
fonte
echo -e "Subject: All that matters\nmail content"? Ou mais agnóstica de plataforma: printf 'Subject: %s\n%s\n' "All that matters" "mail content". Você também pode escrever um pequeno script que use apenas os dois argumentos de string para criar uma linha única ainda mais simples.
22712 Daniel Daniel
Bem, se você adicionar isso como uma resposta que eu poderia aceitá-la ... :)
AndreasT
ah, não, não, desculpe. Por favor, considere minha edição.
AndreasT
O que deve prependfazer? Para saber como acrescentar algo antes, é necessário aguardar até que o comando upstream (por exemplo echo) envie o EOF, para que você possa inserir seus dados antes dele no fluxo antes de passá-lo para o stdout para receber o sendmail. Soa como uma tarefa para um script Shorty Ruby ou Python.
allquixotic
1
Uma abordagem ligeiramente diferente seria usar o mailcomando (às vezes chamado de bsdmail) em vez de sendmaildiretamente. mailtoma uma -s subjectopção opcional , por exemplo: ifconfig -a | mail -s 'Current ifconfig output' [email protected]
Wim Lewis

Respostas:

43
$ echo 1 | (echo 2 && cat)
2
1

Tenho certeza de que existe uma solução melhor, mas isso deve funcionar.

Cláudio
fonte
1
Simples, funcional e demonstrado. +1
Hennes
Existe uma maneira fácil de fazer isso sem o retorno do intervalo?
VenomFangs 21/07
2
@VenomFangs Use printfem vez do segundo echoe você deve ser fino
Trendfischer
> Existe uma maneira fácil de fazer isso sem o retorno do intervalo? -echo -n
KYB
6

Use o que Cláudio disse ou faça o seu:

~ / bin / prepend:

#!/bin/sh
echo -en "$@"
cat -

por exemplo:

$ echo "Splendid SUPANINJA! Let's do it!" |\
     prepend "Subject: Venetian Snares\n"

Subject: Venetian Snares
Splendid SUPANINJA! Lets do it!

Ярослав Рахматуллин
fonte
6

Isso é inspirado na resposta de Cláudio.

Se você não deseja um retorno de interrupção entre suas saídas, adicione o -nparâmetro Será parecido com:

$ echo 1 | (echo -n 2 && cat)

O que dará:

21

VenomFangs
fonte
1
Na verdade, não, não vai. Dá "2 \ n1". Você precisa anexar o "-n" ao segundo eco. Ainda +1. Se você corrigir isso, eu posso aceitar. Não sei o que é justo, pois Cláudio contribuiu mais para a solução.
AndreasT
Desculpe, acho que coloquei -nno lugar errado. De qualquer forma, a actualização deve dar "21 \ n" se você quiser se livrar do \ n seguida, basta adicionar um -n antes do 1.
VenomFangs
1

A partir das peças que reuni ... você poderia fazer algo assim:

echo "Subject: All that matters
`echo "mail content"`" | sendmail blah@blahblah

Observe que eu não fechei as aspas na primeira linha ... porque nem todas as conchas convertem o \ncaractere em uma nova linha ... mas ainda não encontrei uma que não processe uma nova linha real dentro das aspas.

Quando um comando é colocado no caracter `, ele será executado e a saída será injetada no local. Lembre-se de que esse código é um pouco perigoso, pois é possível injetar comandos adicionais em linha que podem comprometer seu sistema facilmente ...

**** editar **** Seguindo o conselho de Claudius, uma opção mais limpa seria assim:

echo -e "Subject: All that matters \n $(echo "mail content") |sendmail blah@blahblah

Mesmo com esse modelo, ele poderia ser explorado.

TheCompWiz
fonte
1
Geralmente, é mais agradável de usar $()do que ``, pois deve ser mais portátil (e também mais legível). Além disso, você pode usar echoa -eopção de fazê-lo traduzir novas linhas ( echo -e "1\n2") ou apenas usar printf, conforme sugerido por Daniel no primeiro comentário.
Claudius
Imediatamente após postar minha resposta ... eu li a sua e gosto mais. Bons pontos.
TheCompWiz
0

Você pode anexar à saída canalizada usando substituição de processo :

$ echo "mail content" | cat <(echo "Subject: All that matters") -
Subject: All that matters
mail content
aparkerlue
fonte