Linux Format

Lua and Conky

Mihalis Tsoukalos covers the essentials for getting started programmin­g in Lua and writing scripts that can be used in Conky, the system monitor.

-

What better way to learn Lua than to put it to use hacking Conky up as the ultimate system monitor with some cool new widgets with the help of Mihalius Tsoukalos.

This article is about Lua, the lightweigh­t, fast and embeddable scripting language and how its scripts can be used in the lightweigh­t Conky system monitor. Lua was created back in 1993 by Roberto Ierusalims­chy – it means ‘moon’ in Portuguese – and it’s currently the leading scripting language for games. Lua’s biggest advantage is that it enables you to build everything yourself, which is also its biggest disadvanta­ge as sometimes you end up having to build everything yourself!

On a Ubuntu system you can install Lua by executing aptget install lua5.2 as root. You can find the precise version of Lua you’re using by running luac -v , which will show you informatio­n similar to the following: Lua 5.2.3 Copyright (C) 1994-2013 Lua.org, PUC-Rio

Lua is a small language with a simple syntax but many capabiliti­es, and the Lua version of the “Hello World!” program is just a single line print("Hello World!") . You can save the aforementi­oned line in a file named hw.lua which can be executed using many ways. The first one is using the lua compiler: $ luac -o hw.luac hw.lua $ ls -l hw.luac -rw-r--r-- 1 mtsouk staff 157 Sep 30 10:31 hw.luac $ lua hw.luac Hello World! $ file hw.luac hw.luac: Lua bytecode, version 5.2

If you run lua without any other command-line arguments, you’ll be sent to the Lua interprete­r, and you can execute hw.lua within the interprete­r as follows: > f = loadfile("hw.lua") > f() Hello World!

A simple Lua example

There’s another way of running Lua, which includes creating an autonomous Lua script. To develop the script version of the “Hello World!” program you’ll need to do: $ cat hw.script #!/usr/bin/env lua print("Hello World!") $ chmod 755 hw.script $ ./hw.script Hello World!

If you already have a compiled file, you can include it in a script and run it as a script using the following technique: #!/usr/bin/env lua dofile("hw.luac")

Now that you know how to compile and execute Lua code, it is time to program something more interestin­g.

The following Lua code finds numbers that belong to the Fibonacci sequence:

You first define a function called Fibonacci. Then, you define a local function named inner() which is a function that’s restricted to a given scope. What you are really doing is storing a function that is used recursivel­y into a local variable. ( seescreens­hot,p84,whichshows­howtocalcu­latethe factorialo­fanunsigne­dintegerin­Luawithout­using

recursion.) The io.write() function used for printing the results is similar to the printf() C function. In case you try to calculate the factorial of a negative integer, the program will stop its execution with the ‘stack overflow’ error message as the current algorithm will create an endless loop when used with a negative integer.

Creating a Class in Lua

Lua doesn’t have a class system! However, Lua has excellent metaprogra­mming facilities that make defining class objects easy. In object-oriented languages, each object is an instance of a specific class. Lua doesn’t include the concept of a class; each object defines its own behaviour and has a shape of its own. In Lua, each object may have a prototype, which is a regular object where the first object looks up any operations that it doesn’t know about. To represent a class in such languages, you simply implement an object to be used exclusivel­y as a prototype for other objects. In Lua you create prototypes in the following way: setmetatab­le(a, {__index = aaa})

After executing the aforementi­oned command, a looks up in aaa for each operation that it doesn’t have. In other words, a is an object of class aaa . Although there are many ways to define and implement classes, the following chunk of code presents a one particular method that is both flexible and quite common:

The presented method uses the setmetatab­le command. In order to create other ‘teams’ that behave similarly to Points, you arrange for these new objects to inherit their operations from Points, using the __index metamethod. Lua tries to look up the punished() function in aTeam and cannot find it. Because aTeam has a metatable that defines __index, it will then look up the punished() function in that metatable. Therefore, aTeam:punished(10) is actually a call to Points. aTeam:punished(aTeam,10).

As you can see, lines that begin with ‘--’ are comments in Lua. Similarly, you can insert a comment at the end of a line after some existing Lua code.

It’s now time to learn more about other Lua features before using them to enhance Conky. Functions in Lua are first-class citizens, therefore they can be passed as function

parameters and assigned to other variables. Lua is a dynamicall­y typed programmin­g language which means that runtime variables have a type despite the fact that variables in a program don’t have types. Until you learn more things about Lua, you can treat the term metatable as ‘a table behind a table’. Another synonym for it is ‘custom behaviour’.

The last thing that you need to know is that Conky works with Lua scripts, so when developing for Conky your final product should be a Lua script. Therefore, the better you know Lua the easier your job will be with Conky. However, Lua scripts used in Conky need not start with the #!/usr/bin/env

lua line.

Configurin­g Conky

Conky is a lightweigh­t system monitor tool for the X Windows system that can display any kind of informatio­n on your desktop. The good thing about Conky is that it can be extended using the built-in Lua support. Conky supports various command line parameters. The most useful one is -d which makes Conky run in the background without the need for an attached terminal. As Conky usually prints messages while running, it is better to combine -d with -q for a quiet Conky operation. In order to use Lua with Conky, you will need to install an extra package. On a Ubuntu Linux system, the required steps are the following: $ wget http://gnome-look.org/CONTENT/contentfil­es/139024-Conky-lua1.tar.gz $ tar zxvf 139024-Conky-lua1.tar.gz $ cd Conky-lua/

Inside the Conky-lua directory there are many tar.gz files named after the names of various Linux distributi­ons (distros). For an Ubuntu system, you should extract the Conky ubuntu-lua.tar.gz file which will create a directory named Conky ubuntu-lua that has the following files in it: clock_rings.lua, conkyrc and new-ubuntu-logo.png. You should now use the conkyrc file you found inside the

Conky ubuntu-lua directory as Conky’s configurat­ion file by simply executing cp conkyrc ~/.conkyrc . You will learn more about the .conkyrc file in a while, but for now look at the following output which shows how Conky uses Lua scripts:

The clock_rings.lua file mentioned in the output of the grep command is the one that can be found inside the Conky ubuntu-lua directory. The clock_rings.lua file must have the function that’s mentioned after the lua_draw_hook_ pre command with the string conky_ in front of it. If the conky_clock_rings() function isn’t present, you are going to get various error messages, when you start Conky, like the one below: Conky: llua_do_call: function conky_clock_rings execution failed: attempt to call a nil value

However, Conky will still run but the area reserved for the clock will be empty. It should be made clear that the clock_ rings.lua file contains only Lua code like the one you saw in the first part of this tutorial. If you open an existing Lua script that works in Conky and aren’t sure which function to set in .conkyrc, look for the function name that begins conky_ .

As with most Linux applicatio­ns, you can change a lot of the Conky options and store them in a text file named .conkyrc which should be inside your home directory. It’s a plain text file that you can change using your favourite text editor (eg Conkyisrun­ningusinga­modified .conkyrc file, picturedbe­low,left). Please bear in mind that Conky requires some system resources, so don’t display too many fields and informatio­n on busy client or server Linux machines.

To keep things organised, it’s better to put the clock_ rings.lua file in a separate directory so make one called .conky inside your home directory and copy the clock_rings. lua file there. For changes to take effect, you’ll need to make alteration­s to the .conkyrc file found inside the Conky ubuntu-lua directory. You should replace the next line lua_load /~.lua/scripts/clock_rings.lua with the following lua_load ~/.conky/clock_rings.lua

This line helps you give Conky the location of the script to use whereas the line that begins with lua_draw_hook_pre tells Conky which function to run from the lua script that was loaded. Before continuing with the rest of the article please make sure that you have no syntax errors in your .conkyrc file by running Conky and seeing the produced output. The .conkyrc file that came with Conky ubuntu-lua.tar.gz produces the Conky look you can see on p87 ( top,right), which is impressive and different to the default Conky look or our custom .conkyrc ( seeleft). As you can understand from both screenshot­s, you can totally change the look of Conky.

Simple Lua scripting

The presented Lua code will make Conky display the “Hello World!” message. As you might imagine, you will need to create a Lua function in a separate file called hwConky.lua and make Conky load this function. The Lua code for implementi­ng the conky_hello_world function is the following: require ‘cairo’

The code is straightfo­rward and easy to understand. The first line shows that the script will use cairo which is the name of the graphics library that Lua will be using to draw graphics displayed in Conky. Then, the implementa­tion of the conky_

hellow_world() starts. The first lines are standard code and should only be present in the conky_ function. They are used for defining the canvas where Lua will draw text and graphics; every Lua script must have these lines. Next, a print() command is given. The tricky thing here is that its output can be seen in the terminal you used to execute the conky binary and not in the graphical Conky area on your desktop. The bad thing is that the message will be displayed every time Conky is being refreshed. The last three commands do some clean up and free some memory. You should also make the next two changes to the .conkyrc file in order to load your desired function:

A slightly modified version of conky_hello_world can be used to actually display text on screen. Please include the following lines of code after the print() function call and restart Conky:

Now, let’s try some more practical Lua code to develop something a little more useful.

More Lua scripting

The name of the Lua file you’re looking for on the LXFDVD is LXF.lua and the name of the main function is conky_ uptime(). The code in LXF.lua reads the three uptime values from the shell and prints their values using the approach that we’ve previously covered.

Apart from the common parts, a big difference this time is that the code calls the external uptime command using the io.popen() function and gets the desired results with a little help from Awk. The os.execute() command cannot do the same job, because it doesn’t allow you to get the results from the command that you have executed. So, the trick to getting the results is to use the following lines of Lua code: local command = ("/usr/bin/uptime | /usr/bin/awk ‘{print $(NF-2)\” \"$(NF-1)\” \"$(NF)}'") local aHandle = assert( io.popen(command , ‘r’ )) local text = aHandle:read('*l')

The first line, above, defines the command that is to be executed, the second line executes the command as a separate process and returns a file handle that you can use to read data from the program. Finally, the last line reads the actual data from the file handle and stores it to a new variable.

There might exist easier ways to do the same thing, but this approach is more generic and can be used in many different situations. Please don’t forget to make the appropriat­e changes to .conkyrc in order to use it.

Remember that as long as you are able to draw, get and display informatio­n using Lua and Conky, only your imaginatio­n can limit what you can do!

 ??  ??
 ??  ?? If you try to calculate the factorial of an integer in Lua that is less than zero, the program will fail as it cannot currently deal with negative numbers.
If you try to calculate the factorial of an integer in Lua that is less than zero, the program will fail as it cannot currently deal with negative numbers.
 ??  ??
 ??  ??
 ??  ?? Running Conky with a custom .conkyrc file allows you to include the informatio­n you want in the output. Just be careful when editing the existing .conkyrc files as they can be fairly complex.
Running Conky with a custom .conkyrc file allows you to include the informatio­n you want in the output. Just be careful when editing the existing .conkyrc files as they can be fairly complex.
 ??  ??
 ??  ??
 ??  ??
 ??  ??
 ??  ??
 ??  ?? This is how Conky‘ s default look changes if you use the .conkyrc file that comes with Conky ubuntulua.tar.gz.
This is how Conky‘ s default look changes if you use the .conkyrc file that comes with Conky ubuntulua.tar.gz.

Newspapers in English

Newspapers from Australia