Home |
Last modified: 16-06-2020 |
Lua is available as a plain interpreter with very limited features, or through richer alternatives:
The reason for module managers is that the Lua interpreter only offers very basic features, and rely on modules for the rest. Modules can be written in pure Lua (plain text) and compiled by the interpreter on the fly, but can also be written in C, and thus require a C compiler in addition to the module manager. Here's an example at how to write, compile, and call a Lua module in C.
An easy way to distribute an application is to zip the Lua interpreter along with modules (pure Lua, and compiled C modules as DLLs).
IDEs: ZeroBrane Studio (up-to-date, cross-platform), Decoda (Last update 2013?), and LuaEdit (Last update December 18, 2011).
The lua-users wiki lists many user-contributed addons for Lua, including tools, libraries, full distributions, and binaries for several platforms. You can get support through the Lua mailing-list.
The -e option allows us to enter code directly into the command line:
% lua -e "print(math.sin(12))"
The -i switch enters interactive mode after running the other argument.
The -l option loads a library:
% lua -i -llib -e "x = 10"
A script can retrieve its arguments through the predefined global variable arg. In a call like % lua script a b c, the interpreter creates the table arg with all the command-line arguments, before running any code. The script name goes into index 0; its first argument ("a" in the example) goes to index 1, and so on:
The simplest way to produce a precompiled file —also called a binary chunk in Lua jargon— is with the luac program that comes in the standard distribution. For instance, the next call creates a new file prog.lc with a precompiled version of a file prog.lua:
$ luac -o prog.lc prog.lua
The Lua interpreter can execute this new file just like normal Lua code, performing exactly as it would with the original source:
$ lua prog.lc
Lua accepts precompiled code mostly anywhere it accepts source code. In particular, both loadfile and load accept precompiled code.
Note: LuaRocks is not available as a Windows installer, and requires the user to edit Windows' system and user environment variables. Also, as of March 2020, it ships with Lua 5.1 so you are required to compile Lua yourself if you want/need a more recent release.
Note: "luarocks config" and "luarocks path" display LuaRocks' settings.
error()
assert()
pcall(), xpcall()
debug.debug, debug.traceback
Here's a simple Lua script that you can use to check that the interpreter works:
Note: The shebang line is not needed in Windows, provided the OS can locate the interpreter (eg. lua5.1.exe).
To run the script, simply call the interpreter with the script name as parameter:
On Linux, alternatively, add the shebang line and make the script executable, respectively:
By default, variables in Lua are global. All local variables must be declared as such. Unlike global variables, a local variable has its scope limited to the block where it is declared.
The Lua distribution comes with a module strict.lua for global-variable checks; it raises an error if we try to assign to a non-existent global inside a function or to use a non-existent global. It is a good habit to use it when developing Lua code.
Lua is a dynamically-typed language. There are no type definitions in the language; each value carries its own type. There are eight basic types in Lua: nil, Boolean, number, string, userdata, function, thread, and table. The function type gives the type name of any given value.
Lua uses two alternative representations for numbers: 64-bit integer numbers, called simply integers, and double-precision floating-point numbers, called simply floats.
The standard string library that comes with Lua assumes one-byte characters, but it can handle UTF-8 strings quite reasonably.
Strings in Lua are immutable values.
We can get the length of a string (in bytes) using the length operator (denoted by #):
Like long comments, multi-line strings can be built using double square brackets, as we do with long comments:
The == operator tests for equality; the ~= operator is the negation of equality.
if true then return end
Alternatively, the function os.exit terminates the execution of a program. Its optional first argument is the return status of the program. It can be a number (zero means a successful execution) or a Boolean (true means a successful execution).
The function os.getenv gets the value of an environment variable. It takes the name of the variable and returns a string with its value:
Alternatively:
Alternatively, this can be done in a single line:
To provide very compact binaries, Lua supports neither POSIX regex nor Perl regular expressions pattern matching. Nevertheless, pattern matching in Lua is a powerful tool, and includes some features that are difficult to match with standard POSIX implementations.
The string library offers four functions based on patterns: find, match, and sub.
Find all occurences in the string
Capture bits:
%n can be used to refer to the n capture:
Note: %0 is the whole match
An optional fourth parameter limits the number of substitutions to be made:
The third argument can also be a function or a table (_G is a predefined table containing all global variables):
Patterns in Lua use the percent sign as an escape. In general, any escaped alphanumeric character has some special meaning (e.g., '%a' matches any letter), while any escaped non-alphanumeric character represents itself (e.g., '%.' matches a dot).
Predefined character classes:
An upper-case version of any of these classes represents the complement of the class. For instance, '%A' represents all non-letter characters:
Note: Extra parentheses are used to discard the second result, which is the number of substitutions.
Unlike ? used by POSIX/Perl regular expressions, Lua uses "-" to specify non-greedy regular expressions:
'%bxy' is used to match balanced strings, where x and y are any two distinct characters; the x acts as an opening character and the y as the closing one. Typically, we use this pattern as '%b()', '%b[]', '%b{}', or '%b<>', but we can use any two distinct characters as delimiters. Again, it's greedy and will take in all the characters until the last occurence of the y character:
'%f[char-set]' represents a frontier pattern. It matches an empty string only if the next character is in char-set but the previous one is not:
An empty capture like '()' has a special meaning in Lua. This pattern captures its position in the subject string, as a number:
(Note that the result of this example is not the same as what we get from string.find, because the position of the second empty capture is after the match.)
The function string.format is a powerful tool for formatting strings and converting numbers to strings :
filename=string.gsub(fullfilename, "(.*/)(.*)", "%2")
page = '<span>item1</span><br>item2<br>item3<br><i>'
for a,b in string.gmatch(page, '<span>.-</span><br>(.-)<br>(.-)<br><i>') do
stuff = a .. b .. "\n========\n"
print(stuff)
end
The standard libraries offer few functions to manipulate date and time in Lua. As usual, all it offers is what is available in the standard C libraries: os.time and os.date.
To maximize portability and embeddability, Lua offers only the functionalities that the ISO C standard offers —namely, basic file manipulation plus some extras.
The I/O library offers two different models for file manipulation: Simple and and complete.
The simple model assumes a current input stream and a current output stream, and its I/O operations operate on these streams. The simple model assumes a current input stream and a current output stream, and its I/O operations operate on these streams. The library initializes the current input stream to the process's standard input (stdin) and the current output stream to the process's standard output (stdout).
print() vs. io.write(): As a rule, you should use print only for quick-and-dirty programs or debugging; always use io.write when you need full control over your output. Unlike print, write adds no extra characters to the output, such as tabs or newlines. Moreover, io.write allows you to redirect your output, whereas print always uses the standard output. Finally, print automatically applies tostring to its arguments; this is handy for debugging, but it also can hide subtle bugs.
The function io.read reads strings from the current input stream. It supports different arguments:
Here's an example:
To iterate line by line:
Here's how to open and read from a file:
os.rename changes the name of a file and os.remove removes (deletes) a file. Note that these functions come from the os library, not the io library, because they manipulate real files, not streams.
Lua's operating-system library and I/O library are mainly interfaces to the underlying system, so their support for UTF-8 strings depends on that underlying system. On Linux, for instance, we can use UTF-8 for file names, but Windows uses UTF-16. Therefore, to manipulate Unicode file names on Windows, we need either extra libraries or changes to the standard Lua libraries. If needed, check the new utf8 library.
Alternatively, use io.lines:
Here's an example that extract all URL's from a text file:
Tables are the only data structuring mechanism in Lua. They are used to represent arrays, sets, records, etc. A table in Lua is essentially an associative array. A table is an array that accepts not only numbers as indices, but also strings or any other value of the language (except nil):
Although we can index a table both with the number 0 and with the string "0", these two values are different and therefore denote different entries in a table.
Constructors are expressions that create and initialize tables. The simplest constructor is the empty constructor, {}, as we have seen. Constructors also initialize lists.
Note: The first element of the constructor has index 1, not 0.
To remove an item, set its value to nil:
To represent a conventional array or a list, we simply use a table with integer keys:
It is customary in Lua to start arrays with one (and not with zero, as in C) and many facilities in Lua stick to this convention.
On tables, the length operator (#) gives the length of the sequence represented by the table:
Append an item to the table:
Note: The length operator only works reliably for sequences, ie. lists without holes. If you really need to handle lists with holes, you should store the length explicitly somewhere.
To traverse key/value pairs:
Due to the way that Lua implements tables, the order that elements appear in a traversal is undefined.
For lists, use the ipairs iterator and Lua ensures the order:
The table library offers several useful functions to operate over lists and sequences
The function table.remove removes and returns an element from the given position in a sequence, moving subsequent elements down to fill the gap. With these two functions (insert/remove), it is straightforward to implement stacks, queues, and double queues.
Use table.pack/unpack:
An unconventional but quite convenient feature of Lua is that functions can return multiple results. This is the case for several predefined functions, such as string.find().
A function in Lua can be variadic, that is, it can take a variable number of arguments:
The three-dot expression is called a vararg expression:
A package is a collection of modules. A module is some code that can be loaded through the function require and that creates and returns a table. Everything that the module exports, such as functions and constants, it defines inside this table, which works as a kind of namespace.
The stand-alone interpreter preloads all standard libraries with code equivalent to this:
To import modules:
The path that require uses to search for Lua files is always the current value of the variable package.path. The path used to search for a C library works exactly in the same way, but its value comes from the variable package.cpath, instead of package.path. The previous example uses .so for all templates; in Windows, a typical path would be more like this one:
.\?.dll;C:\Program Files\Lua502\dll\?.dll
The function package.searchpath encodes all those rules for searching libraries.
The array package.searchers lists the searchers that require uses. When looking for a module, require calls each searcher in the list passing the module name, until one of them finds a loader for the module. If the list ends without a positive response, require raises an error.
Here's how to install the LuaRocks package manager on Debian/Ubuntu, and install ready-to-use modules:
Note: LuaRocks has a lot of dependencies:
Here's a simply module that you can use to check that you can successfully compile and load a module:
Here's how to compile it. You must first provide the Lua source files:
And here's how to load it in Lua:
After compiling LuaSocket, here's how to install and load it:
Here's how to send a datagram to NetCID to display CallerID information on the user's monitor:
http://www.voip-info.org/wiki/view/Asterisk+NetCID
This is a front-end to different database servers. If using SQLite3, you must first compile SQLite3 from www.sqlite.org, then compile LuaSQL for SQLite3. The output file sqlite3.so combines SQLite3 and LuaSQL in a single binary file.
Here's the config file and Makefile to compile LuaSQL and include libsqlite3.o.
Put sqlite3.so in its ./luasql/ directory where Lua can find it. Next, here's how to use it:
Here's how to install SQLite and the Lua package required to use it from Lua:
http://lua-users.org/wiki/GraphicalUserInterfaceToolkits
http = require("socket.http")
mypage = http.request("http://www.google.com")
There are different ways to have a Lua script connect to an HTTP server:
LuaCURL (easy interface; luacurl 1.2.1 is single file with no makefile: luacurl.c, and requires downloading Libcurl; written by Alexander Marinov and Enrico Tassi)
lua-curl (richer; written by Jürgen Hötzel)
Lua-httpd (very basic)
webGet (Windows only)
Here's how to run a server that will open a TCP socket, wait for HTTP queries, use a regex to extract bits from the query, forward the SQL query to the SQLite back-end, and return results to the client:
Here's how to install this as a Windows Service:
How to prevent the server from duplicating the socket, ie. only one client must be able to connect and work with the socket at any time?
In , luasocket-2.0.2-lua-5.1.2-Win32-vc8.zip, no trace of \lib\:
http://w3.impa.br/~diego/software/luasocket/
"it's actually quite difficult to write network code without multithreading. given that networking is largely unreliable speed-wise (to the tune of several milliseconds in bad cases) you really don't want to tie up the cpu waiting for a packet to arrive. normally the networking layer runs continuously in the background, doing all the painful waiting around for packets for you, and then you query it for useful information. however, this requires multithreading." http://www.devmaster.net/forums/showthread.php?t=5890
There are multiple ways to run Lua scripts:
For security reason, Nginx doesn't recommend running scripts through CGI but it can be done.
Alternative : thttpd or mini-httpd + Haserl, or uwsgi with CGI support.
"While nginx is a fine piece of machinery, do you really need such a tight integration and its added complexity? CGI is looked down at, but its simplicity and portability cannot be beaten. A combination of, say, Acme Labs' thttpd and Lua scripts could be a winner, at one tenth of nginx footprint."
http://lua-users.org/lists/lua-l/2012-09/msg00438.html"And if you really think [parsing] is going to make any practical difference, package the entire enchilada into one tight little executable with srclua [1] or such."
http://lua-users.org/lists/lua-l/2012-09/msg00453.htmlWhy use Haserl instead of straight CGI?
Let's go:
/usr/share/doc/mini-httpd
mini_httpd [-C configfile] [-p port] [-d dir] [-dd data_dir] [-c cgipat] [-u user] [-h hostname] [-r] [-v] [-l logfile] [-i pidfile] [-T charset] [-P P3P] [-M maxage] [-S] [-E certfile] [-Y cipher] [-D] [-V]
"/usr/sbin/mini-httpd: started as root without requesting chroot(), warning only"
Remove the read permission bit for the user under which mini_httpd is running, eg:
chmod o-r directory
(In this example, assuming that mini_httpd isn't running as a user or group member of that directory.)
Make sure any shells, utilities, and config files used by your CGI programs and scripts are available. [...] However, one thing you should do is tell syslogd about the chroot tree, so that mini_httpd can still generate syslog messages. Check your system's syslodg man page for how to do this. In FreeBSD you would put something like this in /etc/rc.conf:
syslogd_flags="-l /usr/local/www/data/dev/log"
Substitute in your own chroot tree's pathname, of course. Don't worry about creating the log socket, syslogd wants to do that itself. (You may need to create the dev directory.) In Linux the flag is -a instead of -l, and there may be other differences.
Basic Authentication uses a password file called ".htpasswd", in the directory to be protected. This file is formatted as the familiar colon-separated username/encrypted-password pair, records delimited by newlines. The protection does not carry over to subdirectories. The utility program htpasswd(1) is included to help create and modify .htpasswd files.
/usr/bin/htpasswd
mini_httpd lets you define your own custom error pages for the various HTTP errors. There's a separate file for each error number, all stored in one special directory. The directory name is "errors", at the top of the web directory tree. The error files should be named "errNNN.html", where NNN is the error number. So for example, to make a custom error page for the authentication failure error, which is number 401, you would put your HTML into the file "errors/err401.html". If no custom error file is found for a given error number, then the usual built-in error page is generated.
Based on Using lua wsapi with mini-httpd
WSAPI and luafcgid? Note: WSAPI is to Lua what WSGI is to Python: "WSAPI is an API that abstracts the web server from Lua web applications. By coding against WSAPI your application can run on any of the supported servers and interfaces" (source)
https://github.com/mbalmer/luafcgiMore information here.
Important: "unlike most other SQL databases, SQLite is serverless, which means that using SQLite directly in Nginx will block the Nginx worker processes and ruin the performance. " (source)
So it looks like if your script relies on SQLite, ngx_lua isn't a good idea and you should check the FastCGI/uWSGI options instead.
If you want to find where the binaries will be installed, use "make
-n install"; Use "make install DESTDIR=TMP && tree
TMP" to install it to a given directory.
Note: OpenResty doesn't include support for SQLite, because "using SQLite directly in Nginx will block the Nginx worker processes and ruin the performance." (source)
"You can install it from source by compiling the lua-nginx-module with your existing Nginx. If you chose that path you will also need a Lua interpreter. LuaJIT-2.0.0 is recommended."
http://blog.cloudflare.com/pushing-nginx-to-its-limit-with-lua"The ngx_lua module is for running Lua code directly in the nginx webserver. It is possible to run entire Lua applications in this way but this is not the specific target of that module. Actually, some of the module directives specifically should not be used with long running or complex routines. You will need to recompile Nginx with this module as you cannot just download an Nginx module and use it like that."
"BTW openresty is just regular Nginx with some 3rd party modules bundled in including ngx_lua and the people behind openresty are the same behind ngx_lua"
http://stackoverflow.com/questions/9434448/running-lua-under-nginx-writing-a-website-with-luaAs an alternative to the run-of-the-mill Lua compiler, you can try LuaJIT.
Here's how to compile Nginx to include the ngx_lua module:
Mongoose is a light cross-platform web server that can be compiled to support Lua and SQLite:
April 2014: The build process changed
Note:
Here's hello.lp:
Here's how to play with SQLite:
Note: If SQLite is noticeably slower than other systems, check if the filesystem is ext4.
Examples are available in the lsqlite LuaRocks package (eg. /usr/local/lib/luarocks/rocks/lsqlite3/0.9.1-2/examples/).
DONE mongoose.conf : Format can be either "A B" or ""A=B"
NO Are Lua scripts run through CGI when compiled with "make mongoose-lua"?
NO
Is
it safe to locate and run cgi-bin scripts from within the docroot?
What should
file access rights be for CGI scripts? Is 500 OK?
YES Is it possible to mix Lua with HTML?
docs/LuaSqlite.md doesn't mention Lua scripts with .mg.lua extension: Are HTML with embedded Lua code (.lp) still available in addition to Lua scripts with .mg.lua extension? Which way do you recommend?
Is using LuaRocks OK to install Lua modules and access them from Lua scripts in Mongoose?
What is the difference between lua and luac?
Can Mongoose be launched at boot time as a service? "Mongoose does not detach from terminal." says the docs
Any tips about how to handle HTML forms safely, and generally, about running Mongoose safely, including Lua scripting?
Infos about running Mongoose safely, including Lua scripting
.htaccess: What is a realm? This doesn't work: ./mongoose-lua-sqlite -A .htpasswd 192.168.0.10 joe test -> joe:192.168.0.10:c8b1228323d9839b089a4ebd57c131cf
How to handle 404 instead of just displaying "404 Not Found"?
How to log access/error? Even with "error_log_file mongoose.error.log" in mongoose.conf, no file is created when a 404 occurs
Here's how to install the light-weight Xavante server which is written in Lua so you have everything you need to write a low-scale web server to run Lua scripts:
If you get an error message like "Unable to resolve symbol" when loading a module, try compiling and loading this simple module:
Compile this as a shared library: cc -shared -fPIC -o dummy.so dummy.c
Load in in Lua thusly: lua -ldummy OR lua > print(require"dummy")
Note: The line require "dummy" looks for the function name luaopen_dummy within the shared library.
If that works, try this next:
The Lua interpreter lua51.exe just calls the Lua DLL where most of the logic live. lua51.exe can be put anywhere as long as it can find the DLL through the %PATH% env't variable.
wlua5.1.exe acts like lua51.exe, but with no console output (so a GUI is required to interact with user)
lua5.1.dll and lua51.dll: There was a disagreement about what the DLL should be called, so lua51.dll is a 'proxy' DLL referencing lua5.1.dll. Some extensions link against lua5.1.dll, some against lua51.dll.
luac5.1.exe turns Lua source files into bytecode. Since the interpreter is very fast anyway, the compiler is apparently not often used.
bin2c5.1.exe: Turns Lua scripts into C source.
All binary extensions must be linked against the same C runtime (The Lua for Windows depends on the Microsoft C runtime library MSVCRT.DLL).
Kepler = Lua-based web server
Two ways to build Lua so you can run Unix tools:
Unlike other languages, a function in Lua can return more than one value:
The Lua for Windows executable looks up the DLL extensions in the \clibs subdirectory (in general, Lua uses the LUA_CPATH environment variable)
LuaRocks: For some common rocks, Windows binaries already exist. If a binary rock exists, Lua Rocks will download that rather than the source rock.
Lua is based on ANSI C, which doesn't provide a function to pause a script. Here's a C program that you can compile as a shared library:
www.troubleshooters.com/codecorn/lua/lua_lua_calls_c.htm#_Make_an_msleep_FunctionXavante is a module that handles HTTP requests. WSAPI is a protocol to generate HTTP responses and isn't tied to a specific, underlying web server.
wsapi.exe runs WSAPI-Xavante which binds the handler (Xavante) and the protocol (WSAPI).
Downloaded the basic Windows package from luabinaries.luaforge.net lua5_1_4_Win32:
Here's the Lua for Windows package (C:\Program Files\Lua\5.1):