.. index:: single: Understanding Includes (tutorial) single: head.h (tutorial) single: tail.h (tutorial) .. _tutorial-understanding-includes: Understanding Includes ====================== In the previous section we created a :term:`task`. A task has corresponding :term:`ecf script` which defines the work to be carried out. Scripts are similar to UNIX shell scripts. However :term:`ecf script` includes the addition of "c" like :term:`pre-processing` :term:`directives` and :term:`variable` s. Variables defined in the suite definition can be used in :term:`ecf script`, and provide a configuration mechanism. The default :term:`pre-processing` :term:`directives` are specified by default using the % character. One of the :term:`pre-processing` :term:`directives` is an include. The include is used to inject code into a script, and provide a mechanism for code reuse. If the same code appears in several different :term:`ecf script` files, it should be placed in a include file instead. This then provides a single point of maintenance. For example, every :term:`task` needs to set up the communication with the :term:`ecflow_server` and then tell the server that it (task) has started. This 'boilerplate' code is placed in an include file. .. _tutorial-head_h: head.h ------ The :file:`head.h` include file is placed at the start of :term:`ecf script`. It: * Provides the environment for communication with the :term:`ecflow_server` * Defines script error handling. When the script fails a trap is raised, we inform the server the :term:`task` has :term:`aborted`. * Issues a :term:`child command` to inform the server that job has started. .. code-block:: shell :caption: $HOME/course/head.h #!/bin/ksh set -e # stop the shell on first error set -u # fail when using an undefined variable set -x # echo script lines as they are executed # Defines the variables that are needed for any communication with ECF export ECF_PORT=%ECF_PORT% # The server port number export ECF_HOST=%ECF_HOST% # The name of ecf host that issued this task export ECF_NAME=%ECF_NAME% # The name of this current task export ECF_PASS=%ECF_PASS% # A unique password export ECF_TRYNO=%ECF_TRYNO% # Current try number of the task export ECF_RID=$$ # Define the path where to find ecflow_client # make sure client and server use the *same* version. # Important when there are multiple versions of ecFlow export PATH=/usr/local/apps/ecflow/%ECF_VERSION%/bin:$PATH # Tell ecFlow we have started ecflow_client --init=$$ # Define a error handler ERROR() { set +e # Clear -e flag, so we don't fail wait # wait for background process to stop ecflow_client --abort=trap # Notify ecFlow that something went wrong, using 'trap' as the reason trap 0 # Remove the trap exit 0 # End the script } # Trap any calls to exit and errors caught by the -e flag trap ERROR 0 # Trap any signal that may cause the script to fail trap '{ echo "Killed by a signal"; ERROR ; }' 1 2 3 4 5 6 7 8 10 12 13 15 .. _tutorial-tail_h: tail.h ------ The :file:`tail.h` include file is placed at the end of :term:`ecf script` and is used to inform the server that job has completed. It issues the complete :term:`child command` .. code-block:: shell wait # wait for background process to stop ecflow_client --complete # Notify ecFlow of a normal end trap 0 # Remove all traps exit 0 # End the shell **What to do:** * Create the :ref:`tutorial-head_h` and :ref:`tutorial-tail_h` files in your $HOME/course directory.