I'm trying to create a pipeline with commands like `cmd1 | cmd2 | cmd3`. My goal is to exit the script immediately if `cmd1` fails, since continuing with `cmd2` and `cmd3` would be pointless. I know that using `cmd1 >/tmp/file || exit` works for getting the output of `cmd1`, but I want to avoid writing to a temporary file. I thought of using `mapfile -t output < <(cmd1 || exit)`, but it still executes the next commands, I believe because it's only exiting within the process substitution. What's the best way to handle this? Are traps an option? I'm also looking for advice on defining variables in my script—should I declare them at the top, only when needed, or use functions to manage them?
1 Answer
In a pipeline like `cmd1 | cmd2 | cmd3`, all commands run simultaneously. This means you won't know if `cmd1` failed until after it finishes. Instead, I suggest capturing `cmd1`'s output first and checking its exit status. Here's a neat way to structure it:
```bash
local output # Declare output separately to avoid conflicts with 'local'
output=$(cmd1) || exit
output=$(cmd2 <<< "$output") || exit
cmd3 <<< "$output"
```
Just remember that this approach might slow things down since commands won't run in parallel anymore.

So if I understand correctly, because the commands are executed in parallel, any output from `cmd1` can still be processed by `cmd2` before I know if `cmd1` failed? If `cmd1` is outputting data continuously, does `cmd2` keep processing until it finishes?