I need to form a pipeline of various commands. Some elements of the pipeline, or sequences of elements, are only relevant when some condition holds. Now, I could write:
if [[ $whatever ]]; then
cmd1 | cmd2 | cmd3 | cmd4
else
cmd1 | cmd4
fi
but that means repeating cmd1
and cmd4
, plus, there may be several conditions and I don't want to write nested if's. So, I tried writing this:
if [[ $whatever ]]; then
pipeline_segment="| cmd2 | cmd3"
else
pipeline_segment=""
fi
cmd1 ${pipeline_segment} | cmd4
but - the pipe symbol was not interpreted as an instruction to use a pipe.
How do I have bash execute the pipeline I want it too?
Note: You may assume a bash version of 4 or higher, but only if you must.
Your attempt fails because special symbols lose their syntactical value after expansion. eval
is a way, but as we know it is prone to code injection so it is best avoided. We can try
cmd1 |
if [ condition ]; then
cmd2 | cmd3
else
cat
fi |
cmd4
Though I'd love to skip cat
, I couldn't find a way. Real example:
echo XYZABC |
if true; then
tr Y B | tr Z C
else
cat
fi |
tr X A
outputs ABCABC
and changing the condition to false
outputs AYZABC
.