--- layout: default title: "Config Layer 2: Advanced onAction" short: "Config Layer 2" --- While Layer 4 and 3 feel like normal configuration files, Layer 2 and 1 enter the realm of coding. It is thus supposed you have some coding knowledge when using Layer 2 or 1. Instead of designating actions as strings as in Layer 3 Lua functions can used to do some small scripts right within Lsyncd. This example will convert any file with the suffix ".ps" created in a directory into a PDF. {% highlight lua %} autopdf = { onCreate = function(event) log("Normal", "got an onCreate Event") if string.ends(event.pathname, ".ps") then spawn(event, "/usr/bin/ps2pdf", event.sourcePath) end end } {% endhighlight %} The function can take any valid Lua code. Lsyncd provides you a set of functions to be used in user scripts. log(Category, ...) ------------------ Logs a message into file/stdout/syslog. The first parameter is the logging category all others are strings to be logged. A logging category must start with a capital letter. "Normal" and "Error" are standard categories for log messages. All others are categories for debugging. spawn(Event, Binary, ...) -------------------------- Spawns a new process associated with the event (or event list, see below) as first parameter. The second parameter specifies a binary to call. All others are arguments for the binary. If the third parameter is "<", then along with fourth parameter they will not be passed as arguments to the binary. The fourth parameter is a string that will piped through stdin to the binary. Do not use Lua's ```os.execute``` as opposed to Lsyncd's ```spawn()``` it will block and thus block the whole Lsyncd daemon until the command is completed. Lsyncd's ```spawn``` on the other hand returns immediately while the child process runs. spawnShell(Event, Command, ... ) -------------------------------- The same as spawn(), only it will invoke a shell. Any parameters are referred as $1, $2, $3 and so on in the command. By the way, this is the simple implementation of spawnShell: {% highlight lua %} function spawnShell(agent, command, ...) return spawn(agent, "/bin/sh", "-c", command, "/bin/sh", ...) end {% endhighlight %} terminate(exitcode) ------------------- Lets Lsyncd terminate with ```exitcode```. event ----- Variables of the actions are given by the _event_ field. It has following fields. |Field|Meaning| |:----|:----| | event.config | the configuration as called with sync{} | | event.inlet | see [layer 1](../layer1/) about inlets | | event.etype | the event type. Can be 'ATTRIB', 'CREATE', 'MODIFY', 'DELETE', 'MOVE' | | event.status | the status of the event. 'wait' when it is ready to be spawned and 'active' if there is a process running associated with this event | | event.isdir | true if the event relates to a directory | | event.name | the filename, directories end with a slash | | event.basename | the filename, directories do not end with a slash | | event.path | see ^path of [Layer 3](../layer3/#all-possible-variables) | | event.pathname | see ^pathname of [Layer 3](../layer3/#all-possible-variables) | | event.source | see ^source of [Layer 3](../layer3/#all-possible-variables) | | event.sourcePath | see ^sourcePath of [Layer 3](../layer3/#all-possible-variables) | | event.sourcePathname | see ^sourcePathname of [Layer 3](../layer3/#all-possible-variables) | | event.target | see ^target of [Layer 3](../layer3/#all-possible-variables) | | event.targetPath | see ^targetPath of [Layer 3](../layer3/#all-possible-variables) | | event.targetPathname | see ^targetPathname of [Layer 3](../layer3/#all-possible-variables) | onMove actions have two events as parameter, the origin and the destination of the move. This example will tattle about all moves within the observed directory tree. {% highlight lua %} tattleMove = { onMove = function(oEvent, dEvent) log("Normal", "A moved happened from ", oEvent.pathname, " to ", dEvent.pathname) end, } {% endhighlight %} Action functions have to be short and fast. They are running right within Lsyncd's one and only main thread. If you have to do any more time consuming calculations _spawn{}_ a child process instead. There can only be one child process associated to a event. Layer 3 is nothing else than Lsyncd automatically write Layer 2 functions for you on initialization. Start Lsyncd with ```-log FWrite``` on a Layer 3 configuration to see what functions it dynamically writes and loads for you. Thus Layer 3 and 2 can also be be mixed at will.