ZX: run

zx run PackageID [Args]

This is the most most common task of all: running a program.

The "run" command accepts a single mandatory argument, a PackageID, and any number of following arguments meant to be passed to the application itself.

In the context of this command the PackageID can be ambiguously specified. An omitted realm segment indicates the default open-source realm, "otpr". An omitted or partial version segment indicates the latest version available within the scope of whatever partial version is provided or the absolute latest if omitted entirely.

Consider the following case:

ceverett@takoyaki:~$ zx list versions otpr-hello_world

To run the absolute latest version of the package "otpr-hello_world" the shortest command is:

zx run hello_world

The above command is exactly equivalent to:

zx run otpr-hello_world

The latest available version, v1.1.1, will be run.

If the latest patch version of version 1.0 is desired, however, the command could be given with a partial version specifier:

zx run hello_world-1.0

Because the major and minor version segments are specified version selection is limited in scope to patch release versions of v1.0 of the program. In this case v1.0.1 will be automatically selected and run.

If a program accepts command-line arguments then they can be added to the end of the command. The arguments are passed in as strings, split along whitespace, by the start procedure; arguments with spaces or escapes interpreted by the host shell environment must be quoted.

ceverett@takoyaki:~$ zx run hello_world "Not Sure"
Hello, Not Sure! Hello, World!

The Procedure

The normal "run" procedure looks like this:

  1. ZX connects to its configured realms (if other instances are running it instead proxies through the "prime" instance).
  2. The latest matching target package version is queried if the PackageID does not have a complete version number.
  3. A check is made whether the (now fully qualified) target package is already installed on the system.
    • If not:
      1. The source package (.zsp) fetched from Zomp.
      2. Its signature is verified.
      3. It is unpacked locally in the source cache.
  4. The target's dependency list is read from its zomp.meta file.
  5. The source cache is checked for each dependency; any not found are fetched as above.
  6. All unbuilt dependencies are built.
  7. If the target package is not already built, it is built now.
  8. The application is launched and its install directory is marked as the package home.
  9. Start args (if present) are stored by zx_daemon for retrieval.

(See the zxl page for how to interact with zx_daemon at runtime if you are a project developer.)

Including ZX Calls in Other Scripts

Any fully qualified version number will be respected, all the way down to the dependencies required by that specific version (there are no automatic dependency upgrades when running a program using Zomp/ZX). Because dependencies are statically defined by each package version and only missing packages and dependencies are queried and built when "run" is executed, a package and its dependencies are only subject to the query/fetch/build process the first time it is run. This means that one small (but in special cases significant) advantage of using a fully-qualified PackageID argument is that ZX does not even require network access to launch a program the second time it is called (or if it has been manually installed):

ceverett@takoyaki:~$ time zx run otpr-hello_world-0.1.1
Hello, World!

real    0m1.863s
user    0m0.183s
sys     0m0.121s
ceverett@tahoyaki:~$ time zx run otpr-hello_world-0.1.1
Hello, World!

real    0m0.219s
user    0m0.134s
sys     0m0.036s

An almost 2 second difference doesn't really matter if you're starting a service or a GUI application you intend to run for more than a few seconds itself, but if you are including a ZX-launched program as part of a Bash script that may need to perform an action hundreds of times in a loop then the difference can be quite significant! Keep in mind that the time above includes the time to build and not just query the application (a second run using a partial version number would only do a query, as the latest version would already be built), but every time you start the first running instance of ZX on a system it is required to establish connections to all of its configured realms, and in the (rare) case that multiple redirects are required before it finds an available node for one or more realms the delay before finding a viable node could be significant.

This leads to an important point about use of ZX launched programs in shell scripts: a preparatory query for the latest version is a good step prior to calling any ZX-launched program in a tight loop. In the below example we run a zx program iteratively in a Bash script, using ZX's "latest" query command to automatically generate a fully qualified PackageID:

#! /bin/bash
# Run the latest version of "Hello, World!" in a tight loop 10 times

version=$(zx latest "$package")

for ((i=0;i<10;i++))
    zx run "$program"

If there is a different hello_world package in a realm other than "otpr" then the realm name must always be specified:

zx run other_realm-hello_world

As before, the command above will run the latest version of the hello_world package available from the realm "other_realm", if such a package is available. Note, of course, that while the realm "otpr" is available by default on all ZX installations (unless explicitly removed), any other realms will have to have been added to the Zomp/ZX config by a user or site administrator to make that realm "visible" to ZX.