Skip to content

global os

Extra os library functions

The os library has a few extra functions and variables: os.selfdir, os.exec, os.spawn, os.setenv, os.env, os.gettimeofday, os.times, os.tmpdir, os.type, os.name and os.uname, that we will discuss here.

😱 Types incomplete or incorrect? 🙏 Please contribute!


methods


os.exec


function os.exec(commandline: (string|table))
 -> exit_status integer?
 -> error string?

A variation on os.execute.

Here commandline can be either a single string or a single table.

  • If the argument is a table LuaTeX first checks if there is a value at integer index zero. If there is, this is the command to be executed. Otherwise, it will use the value at integer index one. If neither are present, nothing at all happens.
  • The set of consecutive values starting at integer 1 in the table are the arguments that are passed on to the command (the value at index 1 becomes arg[0]). The command is searched for in the execution path, so there is normally no need to pass on a fully qualified path name.
  • If the argument is a string, then it is automatically converted into a table by splitting on whitespace. In this case, it is impossible for the command and first argument to differ from each other.
  • In the string argument format, whitespace can be protected by putting (part of) an argument inside single or double quotes. One layer of quotes is interpreted by LuaTeX, and all occurrences of \", \' or \\ within the quoted text are unescaped. In the table format, there is no string handling taking place.

This function normally does not return control back to the Lua script: the command will replace the current process. However, it will return the two values nil and error if there was a problem while attempting to execute the command.

On MS Windows, the current process is actually kept in memory until after the execution of the command has finished. This prevents crashes in situations where TeXLua scripts are run inside integrated TeX environments.

The original reason for this command is that it cleans out the current process before starting the new one, making it especially useful for use in TeXLUA.

Example:

---@diagnostic disable-next-line
local exit, err = os.exec(1, 2, 3)
assert.is_nil(exit)
assert.equals(err, "invalid arguments passed")

os.exec("/usr/bin/uname -a")

os.exec({ "/usr/bin/uname", "-a" })

Reference:

@see os.execute

os.spawn


function os.spawn(commandline: (string|table))
 -> exit_status integer?
 -> error string?

A returning version of os.exec, with otherwise identical calling conventions.

If the command ran ok, then the return value is the exit status of the command. Otherwise, it will return the two values nil and error.

Example:

---@diagnostic disable-next-line
local exit, err = os.spawn(1, 2, 3)
assert.is_nil(exit)
assert.equals(err, "invalid arguments passed")

os.spawn("/usr/bin/uname -a")
os.spawn({ "/usr/bin/uname", "-a" })

Reference:

@see os.execute

os.kpsepopen


function os.kpsepopen(
  commandline: string,
  mode: ("r"|"w")
)
 -> exit_status integer?
 -> error string?

This function is similar to io.popen but with a preliminary check of the command by mean of kpse.check_permission

If the command ran ok, then the return value is the same of io.popen; otherwise it will return the two values nil and error.

Reference:

@see io.popen kpse.check_permission

os.setenv


function os.setenv(
  key: string,
  value: string?
)

Set a variable in the environment.

Passing nil instead of a value string will remove the variable.

Reference:

os.sleep


function os.sleep(
  interval: number,
  unit: number?
)
@param interval - By default seconds.

@param unit - Sleep interval / unit seconds.

😱 Types incomplete or incorrect? 🙏 Please contribute!

Example:

local start_time = os.gettimeofday()
os.sleep(1)
local end_time = os.gettimeofday()

assert.is_true(end_time - start_time > 1)
os.sleep(1) -- second
os.sleep(1, 10) -- decisecond
os.sleep(1, 100) -- centisecond
os.sleep(1, 1000) -- millisecond

Reference:

os.gettimeofday


function os.gettimeofday() ->  number

@return - for example 1673390071.0893

😱 Types incomplete or incorrect? 🙏 Please contribute!

Return the current “UNIX time”, but as a float.

This function is not available on the SunOS platforms, so do not use this function for portable documents.

Example:

local time = os.gettimeofday()
assert.is_true(time > 1682153121.3217)

Reference:

os.times


function os.times() ->  os.Times {
    cstime = number,
    cutime = number,
    stime = number,
    utime = number,
}

Return the current process times according to the UNIX C library function “times”.

This function is not available on the MS Windows and SunOS platforms, so do not use this function for portable documents.

{
  cstime = 0.0,
  cutime = 0.0,
  stime = 0.01,
  utime = 0.12
}

Example:

local times = os.times()
assert.is_type(times.cstime, "number")
assert.is_type(times.cutime, "number")
assert.is_type(times.stime, "number")
assert.is_type(times.utime, "number")

Reference:

os.tmpdir


function os.tmpdir(template: string?)
 ->  string?
 -> error string?
@param template - for example luatex.XXXXXX

Create a directory in the “current directory” with the name luatex.XXXXXX where the X-es are replaced by a unique string.

The function also returns this string, so you can lfs.chdir() into it, or nil if it failed to create the directory. The user is responsible for cleaning up at the end of the run, it does not happen automatically.

Example:

lfs.chdir("/tmp")
local dir, err = os.tmpdir()
assert.is_type(dir, "string")
assert.is_true(lfs.isdir("/tmp/" .. dir))

dir, err = os.tmpdir("tmp.XXXXXX")
assert.is_type(dir, "string")
assert.is_true(lfs.isdir("/tmp/" .. dir))

dir, err = os.tmpdir("tmp.X")
assert.is_nil(dir)
assert.equals(err, "Invalid argument to os.tmpdir()")

dir, err = os.tmpdir("tmp.XXXXXXX_suffix")
assert.is_nil(dir)
assert.equals(err, "Invalid argument to os.tmpdir()")

Reference:

os.uname


function os.uname() ->  os.Uname {
    sysname = string,
    machine = string,
    release = string,
    version = string,
    nodename = string,
}

Return a table with specific operating system information acquired at runtime.

Example:

local uname = os.uname()
assert.is_type(type(uname.machine), "string")
assert.is_type(type(uname.nodename), "string")
assert.is_type(type(uname.release), "string")
assert.is_type(type(uname.sysname), "string")
assert.is_type(type(uname.version), "string")

Reference:

os.socketsleep


function os.socketsleep(time: integer)
@param time - time is the number of seconds to sleep for. If time is negative, the function returns immediately.

😱 Types incomplete or incorrect? 🙏 Please contribute!

Freeze the program execution during a given amount of time.

This function is a duplicate of socket.sleep() and is always available. The socket library can be nil in some setups.

Example:

local time = os.socketgettime()
os.socketsleep(1)
assert.is_true(os.socketgettime() - time >= 1)

Reference:

@see socket.sleep

os.socketgettime


function os.socketgettime() -> time number

@return time - for example 1683526723.1653

😱 Types incomplete or incorrect? 🙏 Please contribute!

Return the UNIX time in seconds.

You should subtract the values returned by this function to get meaningful values.

This function is a duplicate of socket.gettime() and is always available. The socket library can be nil in some setups.

Example:

local time = os.socketgettime()
os.socketsleep(1)
assert.is_true(os.socketgettime() - time >= 1)

Reference:

@see socket.gettime

fields


os.selfdir


os.selfdir: string = ""

A variable that holds the directory path of the actual executable.

Example:

assert.is_type(os.selfdir, "string")

Reference:

For example /usr/local/texlive/bin/x86_64-linux

@string

os.env


os.env : table<string,string>

A hash table containing a dump of the variables and values in the process environment at the start of the run.

It is writeable, but the actual environment is not updated automatically.

Reference:

{
  HOME = "/home/user",
  HOSTNAME = "myhost",
  INFOPATH = "/usr/local/texlive/texmf-dist/doc/info",
  LANG = "en_US.UTF-8",
  LANGUAGE = "en_US:en",
  OS = "Linux",
  PAPERSIZE = "a4",
  PATH = "/bin:/sbin",
  TERM = "xterm-256color",
  USER = "user",
  USERNAME = "user",
  ...
}

os.type


os.type : string

A string that gives a global indication of the class of operating system.

The possible values are currently windows, unix, and msdos (you are unlikely to find this value “in the wild”).

Example:

assert.is_type(os.type, "string")

Reference:

os.name


os.name : string

A string that gives a more precise indication of the operating system.

These possible values are not yet fixed, and for os.type values windows and msdos, the os.name values are simply windows and msdos

The list for the type unix is more precise: linux, freebsd, kfreebsd, cygwin, openbsd, solaris, sunos (pre-solaris), hpux, irix, macosx, gnu (hurd), bsd (unknown, but BSD-like), sysv (unknown, but SYSV-like), generic (unknown).

Example:

assert.is_type(os.name, "string")

Reference: