linux cli: conditional command dependent on original program in pipe chain
If I开发者_开发问答 type:
progA | progB && progC
then progC
is conditional on progB
, and not on progA
. Is there a way to both pipe the output of progA
to progB
, and then, after progA
is done (and if I have to wait for progB
to be done too, then that's not a problem) have progC
be conditional on prog A?
Also, I need to keep the pipe -- as in I can't afford to do progA > file; ....; progB < file
and loose the time efficiency.
EDIT: How to use the return code of the first program in a pipe command line is a similar question, but does not have constraint of keeping the pipe, and it also assumes that I have access to the code of progB.
Use a named pipe.
With variations on grep
as progA
and cat
as progB
:
$ cat input foo bar baz $ grep fool < input > fifo & cat fifo & wait %1 && echo good || echo bad [1] 13876 [2] 13877 [1]- Exit 1 grep fool < input > fifo bad [2]+ Done cat fifo $ grep foo < input > fifo & cat fifo & wait %1 && echo good || echo bad [1] 13878 [2] 13879 foo [1]- Done grep foo < input > fifo good [2]+ Done cat fifo
Note that wait
without a job ID will always return 0
no matter what the exit status of the background job was and that wait %1
in a separate command will not work when the job exits before you start the wait
. I wouldn't want to put this into production really. All this was tested on bash
btw and might be slightly different for other shells.
I'm not familiar with a way to do this on plain command line. But you could do this in a shell script, the following would make sure each previous program exited with success and pass the output along to the next program. You'd use it like this myscript.sh progA progB progC
. If you didn't want direct dependency on previous program success you could use a counter and check manually for whatever param order you wanted.
#!/usr/bin/env bash
OUTPUT=""
# loop through each argument
while [ $# -ne 0 ]; do
# run each argument as a command and store output
OUTPUT=$($1 $OUTPUT)
RESULT=$?
# check for success
if [ "$RESULT" -ne "0" ]; then
# do whatever else on error here
exit $RESULT
fi
# next arg
shift
done
精彩评论