Skip to content
Shell & TerminalDeep Dive Published Updated 6 min readViews unavailable

GNU awk `PROCINFO`: Runtime Introspection Without Guesswork

Use GNU awk's PROCINFO for version, platform, process identity, and parsed-identifier diagnostics while probing optional keys and preserving portability boundaries.

The existing AWK overview covers record and field behavior that can be shared across implementations. This narrower guide is about GNU awk’s PROCINFO array: what it can tell a program about its interpreter and process, how to inventory names recognized in the parsed program, and where those observations stop being portable. The examples target the GNU awk 5.4.0 manual and release; they do not turn PROCINFO into a POSIX AWK interface.

That distinction matters in production scripts. awk may resolve to different implementations on different hosts, and GNU extensions can be disabled even when the executable is gawk. If a program depends on PROCINFO, invoke and test it as a GNU awk program rather than silently assuming that every command named awk exposes the same array.

Treat PROCINFO as a structured interface, not one version string

GNU awk documents PROCINFO as an array containing information about the running program. Some entries are guaranteed by the documented interface; others are conditional on features, platform support, or optional build components. The in operator makes that difference explicit:

if ("platform" in PROCINFO)
    print PROCINFO["platform"]
else
    print "platform classification unavailable"

Do not read a possibly absent entry and infer support from an empty-looking value. A feature probe says whether that key is present in this interpreter; PROCINFO["version"] separately reports the gawk version. Prefer that capability check when optional information is all the program needs. If a policy genuinely requires a version threshold, parse the documented version format deliberately instead of comparing version strings lexicographically.

The manual’s feature history gives useful compatibility boundaries: PROCINFO["identifiers"] was introduced in gawk 4.1, and PROCINFO["platform"] in gawk 5.0. A script that uses both should treat those entries independently; an older gawk can still provide other PROCINFO details without having either newer entry. GNU gawk 5.4.0 is the release context used here, not a claim that every distribution installs that exact version.

Separate process identity from platform classification

The documented process-related values include pid, ppid, and pgrpid, as well as uid, euid, gid, and egid. GNU awk defines the identity values from the corresponding system calls (getuid(), geteuid(), getgid(), and getegid()). They are useful in a diagnostic record when a batch job behaves differently under a service manager, scheduled task, or interactive shell.

These are identifiers, not an authorization decision. A numeric effective UID does not reveal every filesystem ACL, supplementary group rule, capability, sandbox, or remote-service policy that may govern an operation. Some systems also provide supplementary group entries as PROCINFO["group1"] through PROCINFO["groupN"]; the manual explicitly recommends testing for those entries with in, rather than assuming a fixed group count.

PROCINFO["platform"] answers a different question: the platform for which gawk was compiled. Its documented values are coarse classes such as "mingw", "os390", "posix", and "vms". In particular, "posix" groups GNU/Linux, Cygwin, macOS, and legacy Unix systems. It is not an operating-system release detector and does not promise that two systems in that class share a kernel feature or command-line utility. Use an actual capability test for the behavior your program needs.

Use the identifier inventory as parse-time metadata

PROCINFO["identifiers"] is a subarray indexed by identifier names used in the AWK program text. The value classifies what gawk knows about each name after parsing: "array", "scalar", "untyped", "builtin", "user", or "extension". The last class identifies extension functions loaded through @load or -l. An "untyped" result is not a runtime type error; it means gawk cannot yet decide whether the identifier will be used as a scalar or an array.

The timing limit is important: the manual says these classifications reflect what gawk knows after parsing and are not updated as the program runs. This makes the subarray useful for a startup report, extension-aware diagnostics, or a static inventory of a known AWK program. It is not a live watch of values, a complete dump of runtime state, or a substitute for SYMTAB when the question is about global variable values.

For predictable reports, explicitly sort the identifiers. By default, AWK array traversal order is undefined; gawk lets a program set PROCINFO["sorted_in"] to a documented order such as "@ind_str_asc". That setting is global to for (name in array) traversals, not local to the one array, so make it deliberately in a standalone reporting program and account for the effect if this code is embedded in a larger script.

A small runtime report with optional-key handling

This program emits tab-separated diagnostic rows and then the parsed identifier inventory. It does not print the full command line, because argument lists can contain paths or values that should not be copied into shared logs.

# runtime-report.awk -- invoke with GNU awk, not an unspecified `awk`.
function show(key, label) {
    if (key in PROCINFO)
        printf "%s\t%s\n", label, PROCINFO[key]
    else
        printf "%s\tunavailable\n", label
}

BEGIN {
    show("version",   "gawk_version")
    show("platform",  "build_platform_class")
    show("pid",       "pid")
    show("ppid",      "parent_pid")
    show("uid",       "real_uid")
    show("euid",      "effective_uid")
    show("gid",       "real_gid")
    show("egid",      "effective_gid")
    show("api_major", "extension_api_major")
    show("api_minor", "extension_api_minor")

    if ("identifiers" in PROCINFO) {
        # This is a global traversal-order setting in gawk.
        PROCINFO["sorted_in"] = "@ind_str_asc"
        for (name in PROCINFO["identifiers"])
            printf "identifier\t%s\t%s\n", name, PROCINFO["identifiers"][name]
    } else {
        print "identifier_inventory\tunavailable"
    }
}

Save it as runtime-report.awk, then run gawk -f runtime-report.awk </dev/null. The extension API version rows are optional: the manual documents them when dynamic extension loading is supported. They describe the extension API, not the gawk interpreter release, so report them as separate fields and do not substitute one for the other. The @ind_str_asc order is string order on array indices; it is deterministic for this report but is not numeric sorting.

If this diagnostic is added to a data-processing program, keep diagnostics separate from its machine-readable result stream. Also remember that PROCINFO["argv"] exposes the command-line arguments seen by gawk, including options and any inline program text passed as an argument; program text read through -f file is not itself an argument in that array. This differs from the ordinary ARGV array after gawk has processed its own options. Dumping the full array indiscriminately can disclose invocation data. Log only the specific fields needed for the incident, and apply the same redaction policy used for other process metadata.

PROCINFO can also change interpreter behavior

Do not assume every element is passive telemetry. The manual lists behavior-affecting entries, including PROCINFO["sorted_in"] for array traversal and PROCINFO["strftime"] for the default format used by strftime(). Other entries configure I/O behavior. If a library changes one of these values, it can affect code outside the library; preserve and restore a prior setting when the interface and surrounding program require that isolation.

Finally, GNU extensions are not guaranteed in another AWK implementation or in gawk compatibility modes. GNU’s manual says --posix disables all gawk extensions; --traditional does too, and POSIXLY_CORRECT makes gawk behave in strict POSIX mode. A program whose contract depends on PROCINFO should not accidentally inherit those modes. For a portable script, isolate the GNU-only report behind an explicit gawk invocation and keep the core data transformation in the dialect you actually promise to support.

Related:

Sources:

Comments