Rura atakujących konstruktu PREPEND coś do stdoutput poprzedniego polecenia

25

Chcę używać sendmaila, aby wysyłać mi rzeczy i chcę to zrobić w oneliner.

echo "mail content" | sendmail emailataddres.com 

Wysyła to bez tematu.

Temat musi znajdować się przed treścią poczty, więc szukam czegoś w stylu:

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

sed i awk są zwykle niewygodne w użyciu i zapamiętywaniu.

EDYCJA : Aby wyjaśnić: echo „Treść wiadomości” to tylko przykład ilustrujący. Muszę być w stanie przygotować rzeczy do standardowych strumieni z dowolnego źródła. np .: ifconfig, zcat itp.

AndreasT
źródło
echo -e "Subject: All that matters\nmail content"? Lub więcej platform agnostyk: printf 'Subject: %s\n%s\n' "All that matters" "mail content". Możesz także napisać mały skrypt, który po prostu bierze dwa argumenty łańcuchowe, aby uczynić jeszcze prostszą jednowierszową.
Daniel Andersson,
Cóż, jeśli dodasz to jako odpowiedź, mogę przyjąć ... :)
AndreasT
ah, nie, nie przepraszam. Proszę traktować mój zmienił.
AndreasT
Co należy prependzrobić Aby wiedzieć, jak coś przygotować, musisz poczekać, aż polecenie echowysyłające (np. ) Wyśle EOF, abyś mógł wstawić swoje dane przed strumieniem, zanim przekaże je na standardowe wyjście, aby otrzymać potok do sendmaila. Brzmi jak zadanie dla krótkiego skryptu Ruby lub Python.
allquixotic
1
Nieco innym podejściem byłoby użycie mailpolecenia (czasami nazywanego bsdmail) zamiast sendmailbezpośredniego. mailma opcjonalną -s subjectopcję, np .: ifconfig -a | mail -s 'Current ifconfig output' [email protected]
Wim Lewis

Odpowiedzi:

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

Jestem całkiem pewien, że istnieje lepsze rozwiązanie, ale tak powinno być.

Klaudiusz
źródło
1
Prosty, funkcjonalny i zademonstrowany. +1
Hennes
Czy istnieje prosty sposób to zrobić bez powrotu złamać?
VenomFangs
2
@VenomFangs Użyj printfzamiast drugiego echoi powinieneś być w porządku
Trendfischer
> Czy istnieje prosty sposób, aby to zrobić bez powrotu po przerwie? -echo -n
Kyb
6

Użyj tego, co powiedział Klaudiusz, lub stwórz własny:

~ / bin / prepend:

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

na przykład:

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

Subject: Venetian Snares
Splendid SUPANINJA! Lets do it!

Ярослав Рахматуллин
źródło
6

Jest to inspirowane odpowiedzią Klaudiusza.

Jeśli nie chcesz powrotu przerwy między wyjściami, dodaj -nparametr. Będzie to wyglądać tak:

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

Co da:

21

VenomFangs
źródło
1
Właściwie, nie to nie. Daje „2 \ n1”. Musisz dołączyć „-n” do drugiego echa. Nadal +1. Jeśli to skorygujesz, mogę to zaakceptować. Nie jestem pewien, co jest sprawiedliwe, ponieważ Klaudiusz najbardziej przyczynił się do rozwiązania.
AndreasT,
Przepraszam, myślę, że umieściłem -nniewłaściwe miejsce. W każdym razie aktualizacja powinna dać „21 \ n”, jeśli chcesz się pozbyć \ n, po prostu dodaj -n przed 1.
VenomFangs
1

Z kawałków, które zebrałem ... możesz zrobić coś takiego:

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

Zauważ, że nie zamykałem cudzysłowów w pierwszym wierszu ... ponieważ nie wszystkie powłoki tłumaczą \nznak na znak nowej linii ... ale jeszcze nie znalazłem takiego, który nie przetworzy prawdziwego nowego wiersza w cudzysłowie.

Gdy polecenie jest zawarte w znaku `, zostanie ono wykonane, a dane wyjściowe zostaną wprowadzone w miejsce. Pamiętaj, że ten fragment kodu jest nieco niebezpieczny, ponieważ możliwe jest wstrzyknięcie dodatkowych poleceń, które mogą z łatwością zagrozić Twojemu systemowi ...

**** edit **** Zgodnie z radą Klaudiusza czystsza opcja wyglądałaby tak:

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

Nawet z tym szablonem można go wykorzystać.

TheCompWiz
źródło
1
Zwykle jest bardziej przyjemny w użyciu $()niż ``, ponieważ ma być bardziej przenośny (i również bardziej czytelny). Ponadto, można użyć echo„s -eopcję, aby go przetłumaczyć nowe linie ( echo -e "1\n2") lub po prostu użyć printf jak sugeruje Daniel w pierwszym komentarzu.
Klaudiusz
Natychmiast po opublikowaniu mojej odpowiedzi ... Czytam twoją i bardziej mi się podoba. Słuszne uwagi.
TheCompWiz,
0

Możesz przejść do wyjścia w potoku za pomocą podstawienia procesu :

$ echo "mail content" | cat <(echo "Subject: All that matters") -
Subject: All that matters
mail content
aparkerlue
źródło