Shell return status, cancel command

It makes sense to stop command execution on %sh{ return 1 }. How do I do that?

The usual strict shell trick works:

%sh{ set -e; return 1; echo "Unreachable" }
1 Like

@cipharius’ trick will stop the shell-script from executing when something fails, but the Kakoune script that called the shell-script will keep going.

Kakoune generally ignores the exit status of a shell command. Although most shell commands use a non-zero exit status to mean “an error occurred”, not all of them do. For example, grep exits with a status of 2 to indicate an error, while 1 means “no lines matched the pattern” which (depending on what you’re doing) isn’t an actual problem. This kind of thing is why set -e isn’t the default.

If you want a shell failure to cause a Kakoune failure, you need to send a fail command back to Kakoune. The usual pattern for doing this looks like:

evaluate-commands %sh{
    if do-a-thing; then
        # it worked, let's continue
    else
        # it failed, cancel everything!
        echo 'fail Could not do-a-thing'
    fi
}

Note that if your %sh{} block is not a parameter to an evaluate-commands command, echoing fail won’t cause a failure.

I haven’t tried this, but it might be possible to cause a shell failure to produce a Kakoune failure by using the trap command, something like this:

evaluate-commands %sh{
    # make the shell quit on first error
    set -e

    # when the shell quits, check the last exit code
    trap 'e=$?; [ "$e" -gt 0 ] && echo "fail shell script returned $e"' EXIT
}

Note that you can’t use $? directly in the error message; testing whether $? is zero clobbers it.

1 Like