I want to conditionally add sort
to a shell pipeline, but I'm getting a syntax error when I try:
want_sorting=0
generate_data() { for ((i=0; i<10; i )); do echo "$RANDOM"; done; }
consume_data() {
while IFS= read -r line; do
echo "got data: $line"
done
}
generate_data |
if [ "$want_sorting" = 1 ]; then
sort |
fi
consume_data
However, this throws a syntax error:
syntax error near unexpected token `fi'
How can I add sort |
to the pipeline only if want_sorting
is set?
CodePudding user response:
The problem with your code is that items are split into pipeline components, each of which has a different copy of the shell running it in parallel; so a single if
statement can't have its fi
split off into a different pipeline component.
You can't make a conditional pipeline entry easily, but you can easily make a pipeline entry decide whether to run a command that does something (like sort
) or one that doesn't do anything at all (like cat
).
generate_data |
if [ "$want_sorting" = 1 ]; then
sort -k1,1
else
cat
fi |
consume_data
Now, the slightly less-easy approach:
To get rid of this copy of cat
one can use a shell function that only conditionally creates the pipeline component with sort
before running whatever was supposed to come later in the pipe; something like:
maybe_sort_then() {
if [ "$want_sorting" = 1 ]; then
sort | "$@"
else
"$@"
fi
}
generate_data |
maybe_sort_then consume_data