Defining the first task
With the suite definition ready, the next step is to create the task script, also called
ecf script. This script typically uses extension .ecf.
Task Script Structure
A common pattern used for defining an ecf script is to consider three sections:
A head section, that sets up the necessary execution environment, including error handling, for the task; and eventually notifies the ecflow_server that the task has started
A body section, which contains the actual work to be done by the task
A tail section, that performs the necessary clean up for the task; and eventually notifies the ecflow_server that the task has completed
The head and tail sections are common amongst all tasks, while the body section is specific to each task.
To avoid code duplication, ecFlow enables placing the head and tail sections in separate files, and then include them in the ecf script using “C-like” preprocessing directives. The process of preprocessing the ecf script and including head and tail files is called the job file generation.
Task Head and Tail
The head and tail sections are placed in separate files, called include files.
These files use variables as a configuration mechanism. The variables
are introduced in between %% characters (e.g. %VARIABLE_NAME%) and are substituted when the job file
is created.
These files are introduced into the ecf script using the %include directive.
Note
The use of
%includedirectives is a generic code reuse mechanism, and can be used to avoid code duplication.Whenever several tasks need to perform the same operation, this can be placed in a separate file, and then included in the ecf script using the
%includedirective.The following
head.hfile, containing the header section, performs the following at the start of the ecf script:
Setup the environment for communication with the ecflow_server
Define script error handling, e.g. when the script fails a trap is raised, and the server is informed that the task has aborted.
Inform the server that job has started, using the
initchild command .Note
Notice how variables, such as
ECF_HOSTandECF_PORT, are used in the script. These variables are automatically generated by ecFlow and can be used as part of any section of the ecf script.1#!/usr/bin/env bash 2 3set -e # stop the shell on first error 4set -u # fail when using an undefined variable 5set -x # echo script lines as they are executed 6 7# 8# Important: Adjust the following to point at the ecFlow install location 9# 10ECFLOW_ROOT_DIR=/path/to/ecflow/%ECF_VERSION% 11 12# Define the variables that are needed for any communication with ECF 13export ECF_PORT=%ECF_PORT% # The server port number 14export ECF_HOST=%ECF_HOST% # The name of ecf host that issued this task 15export ECF_NAME=%ECF_NAME% # The name of this current task 16export ECF_PASS=%ECF_PASS% # A unique password 17export ECF_TRYNO=%ECF_TRYNO% # Current try number of the task 18export ECF_RID=$$ 19 20# Define the path where to find ecflow_client 21# make sure client and server use the *same* version. 22# Important when there are multiple versions of ecFlow 23export PATH=${ECFLOW_ROOT_DIR}/bin:$PATH 24 25# Tell ecFlow the task has started 26ecflow_client --init=$$ 27 28# Define a error handler 29ERROR() { 30 set +e # Clear -e flag, so we don't fail 31 wait # wait for background process to stop 32 ecflow_client --abort=trap # Notify ecFlow that something went wrong 33 trap 0 # Remove the trap 34 exit 0 # End the script 35} 36 37# Trap any calls to exit and errors caught by the -e flag 38trap ERROR 0 39 40# Trap any signal that may cause the script to fail 41trap '{ echo "Killed by a signal"; ERROR ; }' 1 2 3 4 5 6 7 8 10 12 13 15The following
tail.hfile, containing the tail section, performs the following at the end of ecf script:
Waits for any background processes to complete
Informs the server that the task has completed successfully
Cleans up any error handling previously defined
1wait # wait for background process to stop 2ecflow_client --complete # Notify ecFlow of a normal end 3trap 0 # Remove all traps 4exit 0 # End the shell
Task Script
The following t1.ecf file is the ecf script for the task t1.
This script includes the head and tail sections from the files
head.handtail.h, respectively. The body section of this script simply prints a message to standard output, including the value of the variableECF_HOME.ecFlow expects task files to be in a directory structure under
ECF_HOMEthat reflects the hierarchy in the suite. In the example, taskt1is part of the suitetest, so the script for taskt1is expected to be in sub-directorytest.1%include "../head.h" 2echo "I am part of a suite that lives in %ECF_HOME%" 3%include "../tail.h"Important
When using the
%include "<filename>"directive, the path to the include file is given relative to the location of the ecf script file, thus the../in the example above.Note
Notice how the
ECF_HOMEvariable is used in the script. This variable is defined in the suite definition file.
What to do:
Create the
$HOME/course/head.hand$HOME/course/tail.hinclude files based on the examples provided above. Make sure to adjust theECFLOW_ROOT_DIRvariable in thehead.hfile to point to the correct ecFlow installation location.Create the directory structure, and the
$HOME/course/test/t1.ecftask script file based on the example provided above.