#!/bin/bash
subject="subject line"
tmpfile=$(mktemp)
trap 'rm -f "$tmpfile"' EXIT
if command >"$tmpfile" 2>&1; then
subject+=" Success"
else
subject+=" Failure"
fi
mail -s "$subject" my@email.com <"$tmpfile"
So, save the output to a temporary file, then mail the file. Set the subject line according to the exit status of the command before sending. No need for two scripts.
You can't access PIPESTATUS
inside the pipeline as the pipeline hasn't yet finished executing. Also, the external script would not have access to it in any case as it's running in its own environment.
What is also not possible is to be piped the input from a generic command, and then act on the exit states of that command. There is no way to access the exit status of a previous command in a pipeline from within the pipeline itself.
What you could do is to wrap the command in code that outputs a piece of text, signifying success or failure. This text would be piped together with the rest of the data (by necessity, as an extra piece of info at the end):
{ if command 2>&1; then echo SUCCESS; else echo FAILURE; } | shell_script.sh
... with shell_script.sh
being
#!/bin/bash
subject="subject line"
tmpfile=$(mktemp)
trap 'rm -f "$tmpfile"' EXIT
cat >"$tmpfile"
if [[ $(tail -n 1 "$tmpfile") == *SUCCESS* ]]; then
subject+=" Success"
else
subject+=" Failure"
fi
sed '$d' "$tmpfile" | mail -s "$subject" me@mail.com
This still has to save the data to a temporary file to access the last line of it (this is done using cat
which reads standard input by default). It then decides whether it was a success or not and sets the subject accordingly. The data with the last line removed is then mailed.
Another option would be to run the mailer script after running the command (commands in a pipeline are executing concurrently), and then simply pass the exit status, which then would be available, as a command line argument:
command >command.log 2>&1
shell_script.sh "$?" <command.log
rm -f command.log
and the script would look like
#!/bin/bash
subject="subject line"
if [[ $1 == 0 ]]; then
subject+=" Success"
else
subject+=" Failure"
fi
mail -s "$subject" my@email.com
In this case, the data to be mailed is passed on standard input, which the mail
utility will read by default (just like cat
did in the previous example).
command
is meant to be any generic command/job I feed in. How would I change your code so that it's compatible to be run in thecommand | shell_script.sh "subject line"
framework? – nwly Nov 09 '19 at 23:47