# Module: `awful.spawn`

Spawn sub-processes and optionally get their output.

This module provides methods to start programs and supports startup notifications, which allows for callbacks and applying properties to the program after it has been launched. This requires currently that the application supports them.

Frequently asked questions ===

**Rules of thumb when a shell is needed**:

* A shell is required when the commands contain `&&`, `;`, `||`, `&` or any other unix shell language syntax * When shell variables are defined as part of the command * When the command is a shell alias

Note that a shell is **not** a terminal emulator. A terminal emulator is something like XTerm, Gnome-terminal or Konsole. A shell is something like `bash`, `zsh`, `busybox sh` or `Debian ash`.

If you wish to open a process in a terminal window, check that your terminal emulator supports the common -e option. If it does, then something like this should work:

awful.spawn(terminal.." -e my_command")

Note that some terminals, such as rxvt-unicode (urxvt) support full commands using quotes, while other terminal emulators require to use quoting.

**Understanding clients versus PID versus commands versus class**:

A *process* has a *PID* (process identifier). It can have 0, 1 or many *window*s.

A *command* is what is used to start *process*(es). It has no direct relation with *process*, *client* or *window*. When a command is executed, it will usually start a *process* which keeps running until it exits. This however is not always the case as some applications use scripts as command and others use various single-instance mechanisms (usually client/server) and merge with an existing process.

A *client* corresponds to a *window*. It is owned by a process. It can have both a parent and one or many children. A *client* has a *class*, an *instance*, a *role*, and a *type*. See client.class, client.instance, client.role and client.type for more information about these properties.

**Understanding blocking versus asynchronous execution**:

Awesome is single threaded, it means only one thing is executed at any time. But Awesome isn't doomed to be slow. It may not have multiple threads, but it has something called coroutine and also has callbacks. This means things that take time to execute can still do so in the background (using C threads or external process + sockets). When they are done, they can notify the Awesome thread. This works perfectly and avoid blocking Awesome.

If you want to update the text of a wibox.widget.textbox with the output of a shell command, you should use the awful.spawn.easy_async_with_shell command. It is strongly recommended not to use io.popen is explained in the "Getting a command's output" section. Asynchronous execution is at first a bit tricky to understand if you never used that before. The example below should demonstrate how it works.

If we do (but *really*, don't do that):

-- **NEVER, EVER, DO THIS**: your computer will freeze os.execute("sleep 1; echo foo > /tmp/foo.txt") mylabel.text = io.popen("cat /tmp/foo.txt"):read("*all")

The label will display `foo`. But If we do:

-- Don't do this, it won't work. -- Assumes /tmp/foo.txt does not exist awful.spawn.with_shell("sleep 1; echo foo > /tmp/foo.txt") mylabel.text = io.popen("cat /tmp/foo.txt"):read("*all")

Then the label will be **empty**. awful.spawn and awful.spawn.with_shell will **not** block and thus the io.popen will be executed before `sleep 1` finishes. This is why we have async functions to execute shell commands. There are many variants with difference characteristics and complexity. awful.spawn.easy_async is the most common as it is good enough for the general "I want to execute a command and do something with the output when it finishes".

-- This is the correct way local command = "sleep 1; echo foo > /tmp/foo.txt"

awful.spawn.easy_async_with_shell(command, function() awful.spawn.easy_async_with_shell("cat /tmp/foo.txt", function(out) mylabel.text = out end) end)

In this variant, Awesome will not block. Again, like other spawn, you cannot add code outside of the callback function to use the result of the command. The code will be executed before the command is finished so the result won't yet be available.

**Getting a command's output**:

First, do **not** use io.popen **ever**. It is synchronous. Synchronous functions **block everything** until they are done. All visual applications lock (as Awesome no longer responds), you will probably lose some keyboard and mouse events and will have higher latency when playing games. This is also true when reading files synchronously, but this is another topic.

Awesome provides a few ways to get output from commands. One is to use the `Gio` libraries directly. This is usually very complicated, but gives a lot of control on the command execution.

This modules provides with_line_callback and easy_async for convenience. First, lets add this bash command to rc.lua:

local noisy = [[bash -c ' for I in $(seq 1 5); do date echo err >&2 sleep 2 done ']]

It prints a bunch of junk on the standard output (*stdout*) and error (*stderr*) streams. This command would block Awesome for 10 seconds if it were executed synchronously, but will not block it at all using the asynchronous functions.

with_line_callback will execute the callbacks every time a new line is printed by the command:

awful.spawn.with_line_callback(noisy, { stdout = function(line) naughty.notification { message = "LINE:"..line } end, stderr = function(line) naughty.notification { message = "ERR:"..line} end, })

If only the full output is needed, then easy_async is the right choice:

awful.spawn.easy_async(noisy, function(stdout, stderr, reason, exit_code) naughty.notification { message = stdout } end)

**Default applications**:

If the intent is to open a file/document, then it is recommended to use the following standard command. The default application will be selected according to the [Shared MIME-info Database](https://specifications.freedesktop.org/shared-mime-info-spec/latest/) specification. The `xdg-utils` package provided by most distributions includes the `xdg-open` command:

awful.spawn({"xdg-open", "/path/to/file"})

Awesome **does not** manage, modify or otherwise influence the database for default applications. For information about how to do this, consult the [ARCH Linux Wiki](https://wiki.archlinux.org/index.php/default_applications).

If you wish to change how the default applications behave, then consult the [Desktop Entry](https://specifications.freedesktop.org/desktop-entry-spec/latest/) specification.

Spawning applications with specific properties ===

**The startup notification protocol**:

The startup notification protocol is an optional specification implemented by X11 applications to bridge the chain of knowledge between the moment a program is launched to the moment its window (client) is shown. It can be found [on the FreeDesktop.org website](https://www.freedesktop.org/wiki/Specifications/startup-notification-spec/).

Awesome has support for the various events that are part of the protocol, but the most useful is the identifier, usually identified by its `SNID` acronym in the documentation. It isn't usually necessary to even know it exists, as it is all done automatically. However, if more control is required, the identifier can be specified by an environment variable called `DESKTOP_STARTUP_ID`. For example, let us consider execution of the following command:

DESKTOP_STARTUP_ID="something_TIME$(date '+%s')" my_command

This should (if the program correctly implements the protocol) result in `c.startup_id` to at least match `something`. This identifier can then be used in ruled.client to configure the client.

Awesome can automatically set the `DESKTOP_STARTUP_ID` variable. This is used by awful.spawn to specify additional rules for the startup. For example:

awful.spawn("urxvt -e maxima -name CALCULATOR", { floating = true, tag = mouse.screen.selected_tag, placement = awful.placement.bottom_right, })

This can also be used from the command line:

awesome-client 'awful=require("awful"); awful.spawn("urxvt -e maxima -name CALCULATOR", { floating = true, tag = mouse.screen.selected_tag, placement = awful.placement.bottom_right, })'

This table contains the client properties that are valid when used the `sn_rules` or `prop` function argument. They are the same as in ruled.client.

Name | Description
--- | ---
placement | The client default placement on the screen
honor\_padding | When applying the placement, honor the screen padding
honor\_workarea | When applying the placement, honor the screen work area
tag | The client default tag
tags | The client default tags
new\_tag | Create a new tag for this client
switch\_to\_tags | Unselect the current tags and select this client tags
focus | Define if the client should grab focus by default
titlebars\_enabled | Should this client have a titlebar by default
callback | A function to call when this client is ready
marked | If a client is marked or not
is\_fixed | Return if a client has a fixed size or not
immobilized\_horizontal | Is the client immobilized horizontally?
immobilized\_vertical | Is the client immobilized vertically?
floating | The client floating state
x | The x coordinates
y | The y coordinates
width | The width of the client
height | The height of the client
dockable | If the client is dockable
requests\_no\_titlebar | If the client requests not to be decorated with a titlebar
shape | Set the client shape
active | Return true if the client is active (has focus)
window | The X window id
name | The client title
skip\_taskbar | True if the client does not want to be in taskbar
type | The window type
class | The client class
instance | The client instance
pid | The client PID, if available
role | The window role, if available
machine | The machine client is running on
icon\_name | The client name when iconified
icon | The client icon as a surface
icon\_sizes | The available sizes of client icons
screen | Client screen
hidden | Define if the client must be hidden, i
minimized | Define it the client must be iconify, i
size\_hints\_honor | Honor size hints, e
border\_width | The client border width
border\_color | The client border color
urgent | The client urgent state
content | A cairo surface for the client window content
opacity | The client opacity
ontop | The client is on top of every other windows
above | The client is above normal windows
below | The client is below normal windows
fullscreen | The client is fullscreen or not
maximized | The client is maximized (horizontally and vertically) or not
maximized\_horizontal | The client is maximized horizontally or not
maximized\_vertical | The client is maximized vertically or not
transient\_for | The client the window is transient for
group\_window | Window identification unique to a group of windows
leader\_window | Identification unique to windows spawned by the same command
size\_hints | A table with size hints of the client
motif\_wm\_hints | The motif WM hints of the client
sticky | Set the client sticky, i
modal | Indicate if the client is modal
focusable | True if the client can receive the input focus
shape\_bounding | The client's bounding shape as set by awesome as a (native) cairo surface
shape\_clip | The client's clip shape as set by awesome as a (native) cairo surface
shape\_input | The client's input shape as set by awesome as a (native) cairo surface
client\_shape\_bounding | The client's bounding shape as set by the program as a (native) cairo surface
client\_shape\_clip | The client's clip shape as set by the program as a (native) cairo surface
client\_shape\_input | The client's input shape as set by the program as a (native) cairo surface
startup\_id | The FreeDesktop StartId
valid | If the client that this object refers to is still managed by awesome
first\_tag | The first tag of the client
buttons | Get or set mouse buttons bindings for a client
keys | Get or set keys bindings for a client

### Info:

- Copyright: 2008 Julien Danjou,2014 Emmanuel Lepage Vallee
- Originally authored by: Julien Danjou <julien@danjou.info>,Emmanuel Lepage Vallee <elv1313@gmail.com>
  (Full contributors list available on our github project)

## Static module functions

awful.spawn (cmd, sn_rules, callback) -> (integer, nil or string) or string | Spawn a program, and optionally apply properties and/or run a callback. |
awful.spawn.with_shell (cmd) -> (integer, nil or string) or string | Spawn a program using the shell. |
awful.spawn.with_line_callback (cmd, callbacks) -> Integer or string | Spawn a program and asynchronously capture its output line by line. |
awful.spawn.easy_async (cmd, callback) -> Integer or string | Asynchronously spawn a program and capture its output. |
awful.spawn.easy_async_with_shell (cmd, callback) -> Integer or string | Call spawn.easy_async with a shell. |
awful.spawn.read_lines (input_stream, line_callback, done_callback, close) | Read lines from a Gio input stream |
awful.spawn.once (cmd, rules, matcher, unique_id, callback) | Spawn a command if it has not been spawned before. |
awful.spawn.single_instance (cmd, rules, matcher, unique_id, callback) | Spawn a command if an instance is not already running. |
awful.spawn.raise_or_spawn (cmd, rules, matcher, unique_id, callback) -> client | Raise a client if it exists or spawn a new one then raise it. |

## Static module functions

🔗 awful.spawn (cmd, sn_rules, callback) -> (integer, nil or string) or string
  Spawn a program, and optionally apply properties and/or run a callback.

  Applying properties or running a callback requires the program/client to support startup notifications.

  See ruled.client.execute for more details about the format of `sn_rules`.

  ### Parameters:

  Name |  | Type(s) | Description | Default value
  --- | --- | --- | --- | ---
  cmd |  | string or table | The command. | Not applicable
  sn_rules | Optional | table or boolean | A table of properties to be applied after startup; `false` to disable startup notifications. | `true`
  callback | Optional | function | A callback function to be run after startup. | Undefined

  ### Returns:

  1. integer The forked PID.
  2. optional string The startup notification ID, if `sn` is not false, or a `callback` is provided.

  ### Or

  string Error message.
🔗 awful.spawn.with_shell (cmd) -> (integer, nil or string) or string
  Spawn a program using the shell. This calls `cmd` with `$SHELL -c` (via awful.util.shell).

  ### Parameters:

  Name |  | Type(s) | Description
  --- | --- | --- | ---
  cmd |  | string | The command.

  ### Returns:

  1. integer The forked PID.
  2. optional string The startup notification ID, if `sn` is not false, or a `callback` is provided.

  ### Or

  string Error message.
🔗 awful.spawn.with_line_callback (cmd, callbacks) -> Integer or string
  Spawn a program and asynchronously capture its output line by line.

  ### Parameters:

  Name |  | Type(s) | Description
  --- | --- | --- | ---
  cmd |  | string or table | The command.
  callbacks |  | table | Table containing callbacks that should be invoked on various conditions.
  stdout | Optional | function | Function that is called with each line of output on stdout, e.g. `stdout(line)`.
  stderr | Optional | function | Function that is called with each line of output on stderr, e.g. `stderr(line)`.
  output_done | Optional | function | Function to call when no more output is produced.
  exit | Optional | function | Function to call when the spawned process exits. This function gets the exit reason and code as its arguments. The reason can be "exit" or "signal". For "exit", the second argument is the exit code. For "signal", the second argument is the signal causing process termination.

  ### Returns:

  Integer the PID of the forked process.

  ### Or

  string Error message.
🔗 awful.spawn.easy_async (cmd, callback) -> Integer or string
  Asynchronously spawn a program and capture its output. (wraps spawn.with_line_callback).

  ### Parameters:

  Name |  | Type(s) | Description
  --- | --- | --- | ---
  cmd |  | string or table | The command.
  callback |  | table | Function with the following arguments
  stdout |  | string | Output on stdout.
  stderr |  | string | Output on stderr.
  exitreason |  | string | Exit reason ("exit" or "signal").
  exitcode |  | integer | Exit code (exit code or signal number, depending on `exitreason`).

  ### Returns:

  Integer the PID of the forked process.

  ### Or

  string Error message.

  ### See also:

  spawn.with_line_callback | Spawn a program and asynchronously capture its output line by line. | static module functions

🔗 awful.spawn.easy_async_with_shell (cmd, callback) -> Integer or string
  Call spawn.easy_async with a shell. This calls `cmd` with `$SHELL -c` (via awful.util.shell).

  ### Parameters:

  Name |  | Type(s) | Description
  --- | --- | --- | ---
  cmd |  | string | The command.
  callback |  | table | Function with the following arguments
  stdout |  | string | Output on stdout.
  stderr |  | string | Output on stderr.
  exitreason |  | string | Exit reason ("exit" or "signal").
  exitcode |  | integer | Exit code (exit code or signal number, depending on `exitreason`).

  ### Returns:

  Integer the PID of the forked process.

  ### Or

  string Error message.

  ### See also:

  spawn.with_line_callback | Spawn a program and asynchronously capture its output line by line. | static module functions

🔗 awful.spawn.read_lines (input_stream, line_callback, done_callback, close)
  Read lines from a Gio input stream

  ### Parameters:

  Name |  | Type(s) | Description | Default value
  --- | --- | --- | --- | ---
  input_stream |  | Gio.InputStream | The input stream to read from. | Not applicable
  line_callback |  | function | Function that is called with each line read, e.g. `line_callback(line_from_stream)`. | Not applicable
  done_callback | Optional | function | Function that is called when the operation finishes (e.g. due to end of file). | Undefined
  close | Optional | boolean | Should the stream be closed after end-of-file? | `false`

🔗 awful.spawn.once (cmd, rules, matcher, unique_id, callback)
  Spawn a command if it has not been spawned before.

  This function tries its best to preserve the state across `awesome.restart()`.

  By default, when no `unique_id` is specified, this function will generate one by hashing the command and its rules. If you have multiple instance of the same command and rules, you need to specify an UID or only the first one will be executed.

  The rules are standard ruled.client.

  This function depends on the startup notification protocol to be correctly implemented by the command. See client.startup_id for more information. Note that this also won't work with shell or terminal commands.

  ### Parameters:

  Name |  | Type(s) | Description
  --- | --- | --- | ---
  cmd |  | string or table | The command.
  rules | Optional | table | The properties that need to be applied to the client.
  matcher | Optional | function | A matching function to find the instance among running clients.
  unique_id | Optional | string | A string to identify the client so it isn't executed multiple time.
  callback | Optional | function | A callback function when the client is created.

  ### See also:

  ruled.client | Apply properties to a new client based on pre-determined rules. | module

🔗 awful.spawn.single_instance (cmd, rules, matcher, unique_id, callback)
  Spawn a command if an instance is not already running.

  This is like awful.spawn.once, but will spawn new instances if the previous has finished.

  The rules are standard ruled.client.

  This function depends on the startup notification protocol to be correctly implemented by the command. See client.startup_id for more information. Note that this also won't work with shell or terminal commands.

  Note that multiple instances can still be spawned if the command is called faster than the client has time to start.

  ### Parameters:

  Name |  | Type(s) | Description
  --- | --- | --- | ---
  cmd |  | string or table | The command.
  rules | Optional | table | The properties that need to be applied to the client.
  matcher | Optional | function | A matching function to find the instance among running clients.
  unique_id | Optional | string | A string to identify the client so it isn't executed multiple time.
  callback | Optional | function | A callback function when the client is created.

  ### See also:

  ruled.client | Apply properties to a new client based on pre-determined rules. | module

🔗 awful.spawn.raise_or_spawn (cmd, rules, matcher, unique_id, callback) -> client · 1 permission
  Raise a client if it exists or spawn a new one then raise it.

  This function depends on the startup notification protocol to be correctly implemented by the command. See client.startup_id for more information. Note that this also won't work with shell or terminal commands.

  ### Parameters:

  Name |  | Type(s) | Description
  --- | --- | --- | ---
  cmd |  | string or table | The command.
  rules |  | table | The properties that need to be applied to the client.
  matcher | Optional | function | A matching function to find the instance among running clients.
  unique_id | Optional | string | A string to identify the client so it isn't executed multiple time.
  callback | Optional | function | A callback function when the client is created.

  ### Returns:

  client The client if it already exists.

  ### See also:

  ruled.client | Apply properties to a new client based on pre-determined rules. | module

  Click to display more

  ### Requested actions or permissions:

  Class | Permission | Context | Default | Description
  --- | --- | --- | --- | ---
  client | activate | spawn.raise_or_spawn | granted | Activate a client when awful.spawn.raise_or_spawn is called and the client exists.

generated by LDoc 1.5.0