When should post-script run?

Due to the discussion from Use of set -euo pipefail in Cylc generated job script:

When should post-script run? Currently, with a minimal example, post-script only runs if script succeeds. My interpretation of the documentation is that it should always run if script runs. Essentially, its acting as another exit-script from what I can tell. Is this the expected behaviour? If not, and post-script should always run if script runs, then job.sh should be modified to something like:

cylc__job__run_user_scripts() {
    typeset func_name=
    # Run the scripts prior to 'script'. If any fail, fail immediately.
    for func_name in env_script user_env pre_script; do
        cylc__job__run_inst_func "${func_name}" || return
    done

    # post-script should always run if script runs
    typeset rc=0
    typeset rc_post=0
    cylc__job__run_inst_func script || rc=$?
    cylc__job__run_inst_func post-script || rc_post=$?

    # Return the return code from the 'script' if it was non-zero
    if ((rc!=0)); then
        return "$rc"
    fi

    # Otherwise, return the return code from the post-script, whether it is zero or not
    return "$rc_post"
}

Noting that the above should work even if someone has done set +e.

Sorry if the documentation isn’t clear on that.

This might be somewhat more helpful:

Task Implementation — Cylc 8.1.0 documentation

The intention is that a job script functions as a single block of user-defined scripting embedded in some boilerplate code for signal trapping and messaging. If any error occurs (that is not explicitly handled in-script) the whole job script should abort.

It happens that the “single code block” may be constructed from several script items, in order to allow some basic inheritance of code fragments, and that each such item happens to be placed inside a function - but as I recall that’s just for internal tidiness reasons.

Oh, also, in Cylc 8 the user block is executed in a subshell so that users can’t accidentally break the job script by e.g. messing with the Python environment (which is needed when communicating status back to the scheduler).

So, no, the post-script is not supposed to run even if the main script failed. They are just - in principle at least - fragments of a single code block.

If you have a need for something more sophisticated than that, we can by all means discuss it. However, note that in-lined task scripting is supported by Cylc as a convenience for use in simple cases. Best practice is that anything non-trivial should really be put in an external script. Then:

  • you have complete control over what happens
  • you can write it in any language (e.g. Python)
  • it can be edited with appropriate language-specific tools
  • it can be tested separately, outside of the workflow
  • and Cylc just has to detect the global success/error status, of your script
1 Like

Ok, thanks. I don’t need anything sophisticated - I don’t actually tend to use post-script, I just noticed it whilst playing around.

1 Like