1
\$\begingroup\$

I have a piece of bash code that works fine.

for thing in "$things"; do
 output=$(my_program "$thing" 2>&1)
 if [[ $? -eq 0 ]]; then
 echo "$(echo "$output" | tail -1)"
 else
 echo "$(echo "$output" | tail -1)" 1>&2
 fi
done

The idea is to echo the last line of the output from the subcommand to stdout if it worked and to stderr if it didn't work.

Is there a better way to achieve this?

Toby Speight
87.7k14 gold badges104 silver badges325 bronze badges
asked Mar 16, 2021 at 16:05
\$\endgroup\$
1
  • \$\begingroup\$ Welcome to Code Review! I changed the title so that it describes what the code does per site goals: "State what your code does in your title, not your main concerns about it.". Please check that I haven't misrepresented your code, and correct it if I have. \$\endgroup\$ Commented Mar 20, 2021 at 13:21

1 Answer 1

2
\$\begingroup\$

Don't quote $things:

for i in "1 2 3 4"; do
 echo "i=$i"
done
i=1 2 3 4
# Better is
for i in 1 2 3 4; do
 echo "i=$i"
done
i=1
i=2
i=3
i=4

When my_program is written well, errors are written to stderr and normal output to stdout. Your bash code is working well, so the program already uses the right returncode.
Can you change the my_program? When you can add an option -s (silent/summary), the program can make sure only 1 line is written to stdout (when OK) or stderr (when NOK):

for thing in ${things}; do
 my_program -s "${thing}"
done

Or without for-loop

printf "%s\n" ${things} | xargs -L1 -I{} my_program -s "{}"

When you can't change my_program, or you don't want to, move the special handling to a function and remove the additional echo commands:

tail_my_program() {
 output=$(my_program $* 2>&1)
 if (( $? == 0 )); then
 tail -1 <<< "${output}"
 else
 tail -1 <<< "${output}" >&2
 fi
}
for thing in ${things}; do
 tail_my_program "${thing}"
done

Your original solution and my function have a small bug: When my_program writes something to stdout after writing an error message to stderr, the stdout message is selected after an exit 1. This might never happen.

answered Mar 20, 2021 at 11:39
\$\endgroup\$

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.