Costruire bash pipe per anteporre qualcosa allo stdoutput del comando precedente


25

Voglio usare sendmail per inviarmi cose e voglio farlo in un oneliner.

echo "mail content" | sendmail emailataddres.com 

Lo invia senza soggetto.

La riga dell'oggetto deve precedere il contenuto di Mail, quindi sto cercando qualcosa sulla falsariga di:

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

sed e awk tendono ad essere davvero imbarazzanti da usare e ricordare.

EDIT : Solo per chiarire: echo "Contenuto della posta" è solo un esempio illustrativo. Devo essere in grado di anteporre elementi a flussi stdout da qualsiasi fonte. ad esempio: ifconfig, zcat, ecc.


echo -e "Subject: All that matters\nmail content"? O più indipendente dalla piattaforma: printf 'Subject: %s\n%s\n' "All that matters" "mail content". Potresti anche scrivere un piccolo script che prende solo i due argomenti di stringa per creare una riga ancora più semplice.
Daniel Andersson,

Bene, se aggiungi questo come risposta, potrei accettarlo ... :)
AndreasT

ah no, scusami. Per favore, considera la mia modifica.
Andreas,

Cosa dovrebbe prependfare? Per sapere come anteporre qualcosa, devi attendere che il comando upstream (es. echo) Invii l'EOF, in modo da poter inserire i tuoi dati prima di esso nello stream prima di passarli a stdout per essere reindirizzato a sendmail. Sembra un compito per uno script Ruby o Python abbreviato.
allquixotic,

1
Un approccio leggermente diverso sarebbe quello di utilizzare il mailcomando (a volte chiamato bsdmail) anziché sendmaildirettamente. mailaccetta -s subjectun'opzione opzionale , ad esempio: ifconfig -a | mail -s 'Current ifconfig output' me@someaddr.com
Wim Lewis,

Risposte:


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

Sono abbastanza sicuro che esiste una soluzione migliore, ma questo dovrebbe fare.


1
Semplice, funzionale e dimostrato. +1
Hennes,

C'è un modo semplice per farlo senza il ritorno di pausa?
VenomFangs

2
@VenomFangs Usa al printfposto del secondo echoe dovresti stare bene
Trendfischer

> C'è un modo semplice per farlo senza il ritorno di pausa? -echo -n
Kyb,

6

O usa quello che ha detto Claudio o crea il tuo:

~ / Bin / anteporre:

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

per esempio:

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

Subject: Venetian Snares
Splendid SUPANINJA! Lets do it!


6

Questo si ispira alla risposta di Claudio.

Se non si desidera un ritorno di interruzione tra le uscite, aggiungere il -nparametro Questo sembrerà:

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

Che darà:

21


1
In realtà, no non lo farà. Dà "2 \ n1". Devi collegare "-n" alla seconda eco. Ancora +1. Se lo correggi, potrei accettarlo. Non sono sicuro di cosa sia giusto, dal momento che Claudio ha contribuito maggiormente alla soluzione.
AndreasT

Scusa, penso di aver messo il -nposto sbagliato. Ad ogni modo, l'aggiornamento dovrebbe dare "21 \ n" se vuoi sbarazzarti di \ n, quindi aggiungi un -n prima del 1.
VenomFangs

1

Dai pezzi che ho raccolto ... potresti fare qualcosa del genere:

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

Si noti che non ho chiuso le virgolette sulla prima riga ... perché non tutte le shell le traducono \nin un carattere di nuova riga ... ma devo ancora trovarne una che non elabori una nuova riga effettiva tra le virgolette.

Quando un comando è racchiuso nel carattere `, verrà eseguito e l'output verrà iniettato sul posto. Tieni presente che questo codice è un po 'pericoloso in quanto è possibile iniettare comandi aggiuntivi in ​​linea che potrebbero facilmente compromettere il tuo sistema ...

**** modifica **** Seguendo i consigli di Claudio, un'opzione più pulita sarebbe simile a questa:

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

Anche con quel modello, potrebbe essere sfruttato.


1
Di solito è più bello da usare $()piuttosto che `` in quanto dovrebbe essere più portatile (e anche più leggibile). Inoltre, puoi usare l echo' -eopzione per far tradurre Newline ( echo -e "1\n2") o semplicemente usare printf come suggerito da Daniel nel primo commento.
Claudio,

Immediatamente dopo aver pubblicato la mia risposta ... Ho letto la tua e mi piace di più. Punti buoni.
TheCompWiz

0

È possibile anteporre all'output convogliato utilizzando la sostituzione del processo :

$ echo "mail content" | cat <(echo "Subject: All that matters") -
Subject: All that matters
mail content
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.