Q:

Replace exit code based on stdout?

I've got a command I want to do some scripting around, but it returns a non-zero exit code for a scenario I don't care about. This scenario is detectable based on the stdout response, so I want to "correct" the status code so I can do some scripting around it.
e.g.
$ hg evolve
nothing to evolve on current working copy parent
(6 other orphan in the repository, do you want --any or --rev)
$ echo $?
2

Is there some convenient way I can wrap this with pure bash so I can change the status code IFF stdout matches some regex?
e.g.
fixstatus '^nothing to evolve\b' -- hg evolve # would return 0 if stdout from hg evolve matches that regex, otherwise returns whatever it would have normally returned

Something like that. I don't think I can solve it with piping because then the exit code would match that final command.

A:

You can do something like:
output=$( hg evolve )
status=$?
if echo "$output" | grep -q '^nothing to evolve\b'; then
    status=0
fi
sh -c "exit $status"  # Set $?

So, in a function, that could look like:
fixstatus() {
    local output status regex
    regex="$1"
    shift
    output=$( "$@" )
    status=$?
    if echo "$output" | grep -q -- "$regex"; then
        status=0
    fi
    printf "%s\n" "$output"
    return $status
}

And call it like: fixstatus '^nothing to evolve\b' hg evolve
Since you're using bash, you could also use [[ ... =~ ... ]] rather than grep.

