Welcome to Stack Exchange! Lot's of good info here. Thank you for your due diligence first.
The issue I see with your command is that it is "Begging the Question." In other words, it assumes you know the answer before you even start.
Let's have a closer look:
The contents of "file.txt" will go to STDOUT.
If the "cat" command generates any errors, they will do to STDERR.
AFTER the command completes, the exit code is set. 0 = success; anything else is an error.
The issue here is, you don't know if you should execute
command2 until the output has already been sent. Which means, it's gone.
Compare that to this:
cat file.txt | sort
This is, effectively, 2 commands:
cat file.txt 1> temp_file
sort < temp_file
Ok not REAL Unix commands, done this way for clarification.
1: Send STDOUT to "tempfile" (that is the 1> part). Also send STDERR to the console.
2: Run the sort command, and read STDIN from "tempfile".
Putting the pipe
| between the two commands obviates the need for a temp file. The pipe means: Redirect STDOUT from "cat" to STDIN of "sort".
You want to redirect STDOUT the the STDIN of another command, but you do not yet know which command that is, so you cannot redirect it.
Before I get to a possible solution, let me give you a little background:
In Unix, there is a way to execute command the way you want to. To wit:
my_command argument1 argument2 && echo "Success" || echo "Failure"
my_command runs (and returns its exit status) with STDOUT & STDERR on the console, run one or the other of the echoes.
&& means "Do this if the last command was successful"
|| means "Do this if the last command failed"
You are very close with your original command. You have:
cat file.txt | command1 || command2
Let's change that to this:
cat file.txt && command1 || command2
That gets you everything you want, except for the output.
cat file.txt works, then should
command1 read STDOUT and ignore STDERR?
Likewise, if it fails, then should
command2 read STDERR and ignore STDOUT?
Or, should either command read both STDOUT & STDERR?
I'll answer both questions for completeness.
Either way, you'll need a way to store the output for later processing. Normally a temp_file.
Capture STDOUT & STDERR in the same temp_file:
cat file.txt > /tmp/temp_file 2>&1
Capture STDOUT to temp_file#1 and STDERR to temp_file#2:
cat file.txt > /tmp/out_file 2 >/tmp/err_file
command2 allow for a file name on the command line?
command2 allow for a redirect from a file?
command2 < temp_file
command2 read STDIN?
cat temp_file | command1
Note: The Word Count command is an example.
cat temp_file | wc
wc < temp_file
The second form may be problematic in the && || form. I include it here for completeness.
Ultimately, you will have to decide what
command2 need to work.
We can now combine these together:
cat file.txt > /tmp/out_file 2>/tmp/err_file && command1 < /tmp/out_file || command2 < /tmp/err_file
Then delete the temp files:
rm /tmp/out_file /tmp/err_file
That should give you what you want.
I'm sure other guru's here can dream up a way of not using a temp_file. I like to keep thins simple and easily understandable because I am not in a programming shop and I have no idea who will have to maintain my code.