# When should post-script run?

**URL:** <https://cylc.discourse.group/t/when-should-post-script-run/615>\
**Category:** Cylc Support\
**Created:** [March 24, 2023, 1:07am UTC](https://cylc.discourse.group/t/when-should-post-script-run/615 "2023-03-24T01:07:10Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![TomC](https://yyz2.discourse-cdn.com/free1/user_avatar/cylc.discourse.group/tomc/32/115_2.png) [@TomC](https://cylc.discourse.group/u/TomC)\
**Post date:** [March 24, 2023, 1:07am UTC](https://cylc.discourse.group/t/when-should-post-script-run/615/1 "2023-03-24T01:07:10Z")

</div>

Due to the discussion from [Use of set -euo pipefail in Cylc generated job script](https://cylc.discourse.group/t/use-of-set-euo-pipefail-in-cylc-generated-job-script/613/16):

When should post-script run? Currently, with a minimal example, post-script only runs if `script` succeeds. My interpretation of the [documentation](https://cylc.github.io/cylc-doc/latest/html/reference/config/workflow.html#flow.cylc%5Bruntime%5D%5B%3Cnamespace%3E%5Dpost-script) 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:

```bash
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`.

---

<div class="post-metadata">

**Author:** ![hilary.j.oliver](https://yyz2.discourse-cdn.com/free1/user_avatar/cylc.discourse.group/hilary.j.oliver/32/4_2.png) [@hilary.j.oliver](https://cylc.discourse.group/u/hilary.j.oliver)\
**Post date:** [March 24, 2023, 2:31am UTC](https://cylc.discourse.group/t/when-should-post-script-run/615/2 "2023-03-24T02:31:27Z")

</div>

Sorry if the documentation isn’t clear on that.

This might be somewhat more helpful:

[Task Implementation — Cylc 8.1.0 documentation](https://cylc.github.io/cylc-doc/latest/html/user-guide/task-implementation/job-scripts.html)

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

---

<div class="post-metadata">

**Author:** ![TomC](https://yyz2.discourse-cdn.com/free1/user_avatar/cylc.discourse.group/tomc/32/115_2.png) [@TomC](https://cylc.discourse.group/u/TomC)\
**Post date:** [March 24, 2023, 2:39am UTC](https://cylc.discourse.group/t/when-should-post-script-run/615/3 "2023-03-24T02:39:52Z")

</div>

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