Конструкция bash pipe для добавления чего-либо в стандартный вывод предыдущей команды


25

Я хочу использовать sendmail для отправки мне материала и хочу сделать это в личном кабинете.

echo "mail content" | sendmail emailataddres.com 

Посылает это без темы.

Строка темы должна предшествовать содержимому Mail, поэтому я ищу что-то вроде:

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

sed и awk, как правило, очень неудобны в использовании и запоминании.

РЕДАКТИРОВАТЬ : Просто чтобы уточнить: echo "Почтовый контент" является просто иллюстративным примером. Мне нужно иметь возможность добавлять материал к потокам stdout из любого источника. например: ifconfig, zcat и т. д.


echo -e "Subject: All that matters\nmail content"? Или более независимой от платформы printf 'Subject: %s\n%s\n' "All that matters" "mail content". Вы также можете написать небольшой скрипт, который просто принимает два строковых аргумента, чтобы сделать еще более простой однострочный.
Даниэль Андерссон

Ну, если вы добавите это как ответ, я могу принять это ... :)
AndreasT

ах, нет я не извиняюсь Пожалуйста, рассмотрите мое редактирование.
AndreasT

Что prependделать? Чтобы узнать, как что-то добавить, вы должны подождать, пока вышестоящая команда (например, echo) не отправит EOF, чтобы вы могли вставить свои данные перед этим в поток, прежде чем передать их в stdout, чтобы получить канал для sendmail. Звучит как задача для короткого скрипта на Ruby или Python.
allquixotic

1
Немного другой подход будет использовать mailкоманду (иногда называемую bsdmail) вместо sendmailпрямой. mailпринимает необязательный -s subjectпараметр, например: ifconfig -a | mail -s 'Current ifconfig output' me@someaddr.com
Вим Льюис

Ответы:


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

Я почти уверен, что есть более хорошее решение, но это должно сработать.


1
Просто, функционально и наглядно. +1
Хеннес

Есть ли простой способ сделать это без возврата перерыва?
VenomFangs

2
@VenomFangs Используйте printfвместо второго, echoи у вас все будет хорошо
Trendfischer

> Есть ли простой способ сделать это без возврата перерыва? -echo -n
KYB

6

Или используйте то, что сказал Клавдий, или сделайте свое:

~ / Bin / перед именем:

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

например:

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

Subject: Venetian Snares
Splendid SUPANINJA! Lets do it!


6

Это вдохновлено ответом Клавдия.

Если вы не хотите возврата между выходами, добавьте -nпараметр. Это будет выглядеть так:

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

Который даст:

21


1
На самом деле, нет, не будет. Это дает "2 \ n1". Вы должны прикрепить «-n» ко второму эхо. Еще +1. Если вы исправите это, я могу принять это. Я не уверен, что справедливо, так как Клавдий внес наибольший вклад в решение проблемы.
AndreasT

Извините, думаю, я поставил не -nв том месте. В любом случае, обновление должно выдавать «21 \ n», если вы хотите избавиться от \ n, а затем просто добавьте -n перед 1.
VenomFangs

1

Из кусочков, которые я собрал ... вы можете сделать что-то вроде этого:

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

Обратите внимание, что я не закрывал кавычки в первой строке ... потому что не все оболочки переводят их \nв символ новой строки ... но мне еще предстоит найти такую, которая не будет обрабатывать фактическую новую строку внутри кавычек.

Когда команда заключена в символ `, она будет выполнена, а вывод будет введен на месте. Имейте в виду, что этот фрагмент кода немного опасен, так как можно встроить дополнительные команды, которые могут легко скомпрометировать вашу систему ...

**** edit **** Следуя совету Клавдия, более чистый вариант будет выглядеть так:

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

Даже с этим шаблоном его можно использовать.


1
Обычно лучше использовать $(), чем ``, ​​поскольку он должен быть более переносимым (и также более читаемым). Кроме того, вы можете использовать опцию echo's', -eчтобы заставить ее переводить символы новой строки ( echo -e "1\n2"), или просто использовать printf, как предложено Дэниелом в первом комментарии.
Клавдий

Сразу после публикации моего ответа ... Я читаю ваш и мне нравится больше. Хорошие моменты.
TheCompWiz

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.