construction de tuyau bash pour ajouter quelque chose à la sortie standard de la commande précédente

25

Je veux utiliser sendmail pour m'envoyer des trucs et je veux le faire dans un oneliner.

echo "mail content" | sendmail emailataddres.com 

L'envoie sans sujet.

La ligne d'objet doit précéder le contenu du courrier, donc je cherche quelque chose dans le sens de:

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

sed et awk ont ​​tendance à être très difficiles à utiliser et à mémoriser.

EDIT : Juste pour clarifier: echo "Mail content" n'est qu'un exemple illustratif. J'ai besoin de pouvoir ajouter des trucs aux flux standard à partir de n'importe quelle source. par exemple: ifconfig, zcat, etc.

AndreasT
la source
echo -e "Subject: All that matters\nmail content"? Ou plus agnostique plate - forme: printf 'Subject: %s\n%s\n' "All that matters" "mail content". Vous pouvez également écrire un petit script qui prend simplement les deux arguments de chaîne pour créer une ligne encore plus simple.
Daniel Andersson
Eh bien, si vous ajoutez ceci comme réponse, je pourrais l'accepter ... :)
AndreasT
ah non, désolé. Veuillez considérer mon montage.
AndreasT
Que faut prepend- il faire? Afin de savoir comment ajouter quelque chose, vous devez attendre jusqu'à ce que la commande en amont (par exemple echo) envoie l'EOF, afin que vous puissiez insérer vos données en amont dans le flux avant de les passer à stdout pour être canalisées vers sendmail. Cela ressemble à une tâche pour un script Ruby ou Python court.
allquixotic
1
Une approche légèrement différente serait d'utiliser la mailcommande (parfois appelée bsdmail) au lieu de sendmaildirectement. mailprend une -s subjectoption facultative , par exemple: ifconfig -a | mail -s 'Current ifconfig output' [email protected]
Wim Lewis

Réponses:

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

Je suis presque sûr qu'il existe une meilleure solution, mais cela devrait suffire.

Claudius
la source
1
Simple, fonctionnel et démontré. +1
Hennes
Existe-t-il un moyen facile de le faire sans le retour de pause?
VenomFangs
2
@VenomFangs Utilisez printfau lieu de la seconde echoet tout devrait bien se
passer
> Existe-t-il un moyen facile de le faire sans le retour de pause? -echo -n
kyb du
6

Utilisez ce que Claudius a dit ou créez le vôtre:

~ / bin / prepend:

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

par exemple:

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

Subject: Venetian Snares
Splendid SUPANINJA! Lets do it!

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

Ceci est inspiré par la réponse de Claudius.

Si vous ne voulez pas de retour de pause entre vos sorties, ajoutez le -nparam. Cela ressemblera à:

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

Ce qui donnera:

21

VenomFangs
la source
1
En fait, non. Il donne "2 \ n1". Vous devez attacher le "-n" au deuxième écho. Toujours +1. Si vous corrigez cela, je pourrais l'accepter. Je ne sais pas ce qui est juste, car Claudius a le plus contribué à la solution.
AndreasT
Désolé, je pense que j'ai mis -nle mauvais endroit. Quoi qu'il en soit, la mise à jour devrait donner "21 \ n" si vous voulez vous débarrasser du \ n, puis ajoutez simplement un -n avant le 1.
VenomFangs
1

D'après les morceaux que j'ai rassemblés ... vous pourriez faire quelque chose comme ceci:

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

Notez que je n'ai pas fermé les guillemets sur la première ligne ... parce que tous les shells ne traduisent pas le caractère \nen nouvelle ligne ... mais je n'ai pas encore trouvé celui qui ne traitera pas une nouvelle ligne réelle à l'intérieur des guillemets.

Lorsqu'une commande est placée dans le caractère `, elle sera exécutée et la sortie sera injectée sur place. Gardez à l'esprit que ce morceau de code est un peu dangereux car il est possible d'injecter des commandes supplémentaires en ligne qui pourraient facilement compromettre votre système ...

**** modifier **** Suivant les conseils de Claudius, une option plus propre ressemblerait à ceci:

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

Même avec ce modèle, il pourrait être exploité.

TheCompWiz
la source
1
Il est généralement plus agréable à utiliser $()plutôt que `` car il est censé être plus portable (et aussi plus lisible). De plus, vous pouvez utiliser echol' -eoption de pour le faire traduire newlines ( echo -e "1\n2") ou simplement utiliser printf comme suggéré par Daniel dans le premier commentaire.
Claudius
Immédiatement après avoir posté ma réponse ... J'ai lu la vôtre et je l'aime mieux. Bons points.
TheCompWiz
0

Vous pouvez ajouter un préfixe à la sortie canalisée à l'aide de la substitution de processus :

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