NAME
act - administrative compatibility tool
SYNOPSIS
act [OPTION]... ACTION
[ARGUMENTS]...
act [-h|-V]
DESCRIPTION
act provides a consistent interface for system administration activities across multiple types of Unix-like operating system, with minimal overhead.
The tool simplifies basic package and service management across a heterogeneous estate. It can be used in scripted bulk queries or updates over SSH, interactively via a terminal multiplexer such as tmux(1), or it can be used as an OS-independent layer for a command and control system. More advanced activities are left to the native administrative commands.
User-defined hooks can be added, which run before and after each action; see the HOOKS section. For example, these may be useful if you are running a file system monitoring tool such as iwatch(8) and would like to ensure it's stopped before packages are updated, and started again afterwards.
User-defined actions can also be added - see the EXTENSIONS section. These can be particularly useful if you need to provide a way to run custom functions while re-using existing access controls such as sudo(8) entries or endpoint management systems.
OPTIONS
Note that options must come before the actions and arguments.
- -n, --non-interactive
-
Run all actions in non-interactive mode even when standard input is a terminal.
- -i, --interactive
-
Run all actions in interactive mode even when standard input is not a terminal.
- -v, --verbose
-
Write details of the commands being called to stderr.
- -vv, --debug
-
Write debugging information to stderr.
- -q, --quiet
-
Discard all errors.
- -qq, --very-quiet
-
Discard all output as well as all errors.
- -j, --json
-
Produce output in JSON format, which will be an object containing an exitStatus integer, strings named action and arguments, and an item named output which will be a string, an array of strings, a boolean, or an array of objects, depending on which action was run. If there was a problem with option parsing, the last error message will be reported in a string named error.
- -o, --output FILE
-
Redirect standard output so it appends to FILE.
- -t, --tee FILE
-
Append a copy of the raw standard output to FILE. Normally, output is only emitted at the end of processing; with --tee, output is added to FILE as it is generated, which can be useful if the caller wants to be able to report the progress of long-running actions like “package-upgrade-all” back to a central point. If the --json option is also active, note that the JSON data is not copied to the --tee file. For actions that produce structured output, the --tee file will contain the raw tab-separated records (without a header line), regardless of whether --json was used.
- -e, --error FILE
-
Redirect standard error so it appends to FILE.
- -h, --help
-
Print a usage message on standard output and exit successfully.
- -V, --version
-
Print version information on standard output and exit successfully.
ACTIONS
Actions which produce structured output - “package-info”, “package-upgrade-list”, “package-list-installed”, “service-list-all”, and “system-info” - will write records in tab-separated value format, with the first record prefixed by a header line. If the --json option is used, these records will be presented as an array of JSON objects instead.
See the CAVEATS section for details of what happens to the output when running in interactive mode on a terminal.
Individual package management
These actions take one or more arguments, which are the names of the packages to operate on. Package names may not contain /, ;, spaces, or begin with -.
- package-install
-
Install one or more packages. Depending on the package manager, this may also automatically install other packages on which the specified packages depend.
- package-upgrade
-
Upgrade one or more packages to the latest available version.
- package-downgrade
-
Downgrade one or more packages to the available version.
- package-remove
-
Remove (uninstall) one or more packages. Depending on the package manager, this may automatically remove other packages in the process. Use this action with caution.
- package-reinstall
-
Reinstall one or more packages.
- package-info
-
Output structured information about one or more packages. One record is produced per package, containing the following fields:
- package
-
The name of the package.
- architecture
-
The package architecture, as reported by the package manager.
- version
-
The version of the package.
- installEpoch
-
The epoch time at which the package was installed.
- vendor
-
The package vendor, as reported by the package manager.
- type
-
The type of package, such as "deb".
- summary
-
The package summary or short description.
- package-files
-
Output a list of the files owned by the named package.
- package-owning-file
-
Given a filename, output the name of the package which owns that file, if any.
Bulk package management
These actions do not take any arguments.
- package-cache-update
-
Update the package manager's cache of software repository information.
- package-cache-clean
-
Clean up the package manager's caches of downloaded files and information.
- package-upgrade-list
-
Output structured information about packages for which upgrades are available. One record is produced per package, containing the following fields:
- package
-
The name of the package.
- architecture
-
The package architecture, as reported by the package manager.
- targetVersion
-
The version of the package that will be installed by the upgrade.
- repository
-
The name of the repository from which the package will be retrieved.
- type
-
The type of package, such as "deb".
- package-upgrade-all
-
Upgrade all packages for which upgrades are available.
- package-list-installed
-
Output structured information about all currently installed packages, in the same format as the package-info action listed above.
Individual service management
These actions take a single argument, which is the service to act upon.
- service-start
-
Start the service.
- service-stop
-
Stop the service.
- service-restart
-
Stop and start the service; if it was not running, this will start it.
- service-try-restart
-
Restart the service, but only if it was already running, otherwise do nothing.
- service-reload
-
Tell the service to reload its configuration.
- service-enable
-
Enable the service so that it will start on boot. This will fail if the service is masked. Note that this does not start the service.
- service-disable
-
Disable the service so that it will not start on boot. This will fail if the service is masked. Note that this does not stop the service if it is already running.
- service-mask
-
Mask the service so that it will not start on boot and cannot be started. Note that this does not stop the service if it is already running.
- service-unmask
-
Unmask the service so that it can be enabled, disabled, stopped, and started. Note that this does not enable, disable, stop, or start the service.
- service-is-known
-
Output "true" and exit with status 0 if the service is known to the system at all, or output "false" and exit with status 1 if it is not.
- service-is-running
-
Output "true" and exit with status 0 if the service is running, or output "false" and exit with status 1 if it is not. It is not an error if the service is not known to the system.
- service-is-enabled
-
Output "true" and exit with status 0 if the service is enabled, or output "false" and exit with status 1 if it is not. It is not an error if the service is not known to the system.
- service-is-masked
-
Output "true" and exit with status 0 if the service is masked, or output "false" and exit with status 1 if it is not. It is not an error if the service is not known to the system.
Bulk service management
These actions do not take any arguments.
- service-list-all
-
Output structured information about all services known to the system. One record is produced per service, containing the following fields:
- service
-
The name of the service.
- boot
-
The startup status of the service - enabled, disabled, or masked.
- active
-
The current status of the service - inactive, activating, or active.
- description
-
A short description of the service.
System information
These actions do not take any arguments.
- system-info
-
Output structured information about this system. One record is produced, containing the following fields:
- machineIdHash
-
The machine ID after prefixing with "act-" and passing through SHA-256, expressed as hex digits, or "-" if unknown. See machine-id(5), or on OpenBSD, the definition of hw.uuid in sysctl(2).
- dnsHost
-
The host name.
- dnsDomain
-
The DNS domain name.
- kernelName
-
The name of the kernel, such as "Linux" or "FreeBSD".
- kernelVersion
-
The version of the kernel.
- arch
-
The kernel architecture, as reported by “uname -m”.
- ramSize
-
The total amount of RAM visible to the operating system, in bytes (this is an integer field).
- cpuCount
-
The number of CPUs (this is an integer field).
- ipAddresses
-
A comma-seperated list of IPv4 and IPv6 addresses the system is using.
- osName
-
The human-readable name of the operating system, such as "Debian GNU/Linux".
- osId
-
The machine-readable name of the operating system, such as "debian".
- osVersionId
-
The machine-readable operating system version, typically formatted like a version number.
- osBuildId
-
The system image used as a base, if applicable.
- osLike
-
A space-separated list of machine-readable operating system names that this system is similar to, most similar one first - for example an AlmaLinux system may say "rhel centos fedora".
- osCpeName
-
The name of the operating system in the Common Platform Enumeration Specification format.
- osPrettyName
-
The full name of this particular version of the operating system, in human-readable format.
Any unknown or empty values will be shown as "-" (or 0, for integer fields).
The fields whose names start with "os" are taken from the os-release(5) file, if it is available.
- listening-ports
-
Output structured records describing the open network ports. Each record contains the following fields:
- protocol
-
The protocol - either tcp or udp, possibly suffixed with a 4 or 6 to denote IPv4 or IPv6, depending on the system.
- ip
-
The local IP address to which the port is bound, or 0.0.0.0 (IPv4) or [::] (IPv6) for no specific IP.
- port
-
The port number (this is an integer field).
- pid
-
The process ID that is listening on this port, or 0 if not known (this is an integer field).
- command
-
The name of the process that is listening on this port, if known ("-" if not).
If more than one process is listening on the same port, and the OS provides a way to list them all, then a record will be output for each process. This means that the same protocol and port may appear multiple times.
HOOKS
User-defined hooks can be placed in the hook directory, which is usually /usr/libexec/act/hook/. In the hook directory, there is a "pre" and "post" subdirectory for every action, as well as for the overall action class (which is the part of the action up to the first hyphen), and for all actions.
Within those subdirectories, every file ending in ".sh" will be executed in alphanumeric order.
For example, the package-install action will call these scripts before performing the action:
/usr/libexec/act/hook/pre/all/*.sh
/usr/libexec/act/hook/pre/package/*.sh
/usr/libexec/act/hook/pre/package-install/*.sh
And then, after the action:
/usr/libexec/act/hook/post/package-install/*.sh
/usr/libexec/act/hook/post/package/*.sh
/usr/libexec/act/hook/post/all/*.sh
The scripts should ideally avoid producing any direct output. Use the internal act functions to write debugging, informational, and error messages, and to run important commands - see the INTERNAL FUNCTIONS section.
Each script will be called with the action variable set to the action, the actionArguments variable set to the action's arguments, and for the "post" hooks, the exitStatus variable set to the exit status of the action. Hook scripts should not modify these variables.
Recursion is avoided by preventing future invocations of act from loading the same hooks again. The ACT_HOOKS_LOADED environment variable is used by act to pass lists of the hooks it has already loaded between its different invocations within the same run. It should therefore be safe to call act from within a hook script.
Hook example
To stop the iwatch(8) service before applying package changes, and start it again afterwards - but only if it was running already - place this in /usr/libexec/act/hook/pre/package/00-iwatch-stop.sh:
iwatchNeedsStarting=false
if act -qq service-is-running iwatch; then
act -qq service-stop iwatch
iwatchNeedsStarting=true
fi
Then, place this in /usr/libexec/act/hook/post/package/99-iwatch-start.sh:
if test "${iwatchNeedsStarting}" = "true"; then
act -qq service-start iwatch
fi
Hooks like this could be included in standardised configuration deployed to all systems using whatever management mechanism is appropriate for your estate.
EXTENSIONS
User-defined extensions can be placed in the extension directory, which is usually /usr/libexec/act/extension/. Within the extension directory, every file ending in ".sh" will be executed in alphanumeric order, when an otherwise unknown action is specified or the --help option is used.
Each extension file must produce no output or cause any side effects when loaded, but should only define new action functions, and register those new actions by calling the actRegisterExtension function with these arguments:
- ACTION
-
The action name on the command line, such as “custom-action”.
- MIN-ARGS
-
The minimum number of arguments accepted by this action (which may be zero).
- MAX-ARGS
-
The maximum number of arguments accepted by this action (zero means unlimited, unless MIN-ARGS is also zero - both being zero means that this action accepts no arguments).
- DESCRIPTION
-
A very short description of this action, for use by --help.
- DATA-TYPE
-
The type of data this action will output; this defaults to "string" if not supplied.
The data type of an action, which determines how --json handles its output, can be one of the following:
- string
-
A string of arbitrary length which may span multiple lines. This is the default. Actions with this data type will automatically have their raw output copied to the terminal when run in interactive mode (see the CAVEATS section).
- strings
-
A list of strings, one per line, such as a list of filenames.
- boolean
-
A single boolean value, which must be either "true" or "false".
- list
-
A list of records, one per line, with the word after "list" being a comma-separated list of field names. A field name can be suffixed by ":I" to indicate that its value will be an integer rather than a string. For example, "list package,installEpoch:I" describes records with two fields named "package" and "installEpoch", where "installEpoch" is an integer.
The function name associated with an action is always the ACTION in lower case, first letter of each word upper case, with hyphens removed, and prefixed by actExtension. For example, the function for “custom-action” would be actExtensionCustomAction.
Each function will be called with the action variable set to the action, and the actionArguments variable set to the action's arguments.
Within a function, use the internal act functions to write debugging, informational, and error messages, and to run important commands - see the INTERNAL FUNCTIONS section.
Functions must return 0, 1, or 2, as described in the EXIT STATUS section.
If an action function is writing structured records, it must write one record per line, in the order specified by the data type registered with actRegisterExtension, with the values within the record separated by tabs (ASCII 9).
Class functions may also be defined. The action class is the first word of an action, when the action name has more than one word - so “custom-action” has a class of “custom”. This can be useful when the same preparatory work is needed for several actions of the same type.
The function name for a class is determined in the same way as the action function, so in this example it would be actExtensionCustom. When a class function is available for an action, the class function will be called first, before the action function. Because class functions are implied by action definitions, there is no need to register them separately.
INTERNAL FUNCTIONS
The following functions are available from within hooks and extensions.
- actDebug
-
Write a debugging message (governed by -vv),
- actInfo
-
Write an informational message (governed by -v),
- actError
-
Write an error message.
- actRun
-
Report that a command is about to be run, using actInfo, and then run the command and return its exit status.
EXIT STATUS
- 0
-
Action completed successfully.
- 1
-
Action not completed successfully.
- 2
-
Action not supported on this operating system.
CAVEATS
When running some package management actions in interactive mode on a terminal, raw output will be written directly to the terminal - so the operator can see any interactive prompts - while also being captured for processing. After completion, the processed output is then produced. This means that when running act on a terminal without redirecting the output and without using --non-interactive, you may see information appearing twice. This applies only to actions with unstructured output, such as “package-upgrade”.
Service masking is not supported on FreeBSD or OpenBSD, or with OpenRC.
On systems which use System V init, service masking is emulated by changing the permissions of the service file in /etc/init.d to 000.
The “activating” service status is only supported on systems using systemd(1). All other service managers will only show a status of “active” or “inactive”.
The “service-list-all” action leaves the short description empty for all services on OpenBSD.
On OpenRC systems, all service actions operate only on the current runlevel.
Downgrading packages with “package-downgrade” is unsupported on FreeBSD, Arch Linux, and Alpine Linux.
Reinstalling packages with “package-reinstall” is unsupported on Alpine Linux.
Refreshing and cleaning the package cache is unsupported on OpenBSD.
On OpenBSD, the package installation timestamp reported by “package-info” and “package-list-installed” is derived from the last-modification time of the associated directory under /var/db/pkg/, which is not a documented method and may be unreliable.
On Alpine Linux, the package installation time is not recorded, so act always reports it as zero on that platform.
When listing upgrades with “package-upgrade-list”, neither OpenBSD nor Alpine Linux provide repository information, so the repository is always reported as “-” on those platforms.
The process ID and command cannot be read by “listening-ports” on OpenBSD, and the command will be truncated on FreeBSD. Also, on Linux systems where netstat(8) must be used by this action because ss(8) is either unavailable or too old, only one process can be listed per port.
REPORTING BUGS
Please report any bugs to act@ivarch.com.
Alternatively, use the issue tracker linked from the act home page: <https://www.ivarch.com/programs/act.shtml>
SEE ALSO
apt-get(8), zypper(8), yum(8), dnf(8), pacman(8), apk(8), pkg(8), pkg_add(8), pkg_delete(8), pkg_info(8), service(8), rcctl(8), rc-service(8), rc-update(8), systemctl(1), machine-id(5), os-release(5), netstat(8), ss(8)
COPYRIGHT
Copyright © 2023-2024 Andrew Wood.
License GPLv3+: GNU GPL version 3 or later <https://www.gnu.org/licenses/gpl-3.0.html>.
This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law.