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

getconf in Shell Scripts: Query Capabilities Instead of Guessing the OS

Use getconf for standardized limits and options while distinguishing runtime capabilities from kernel identity and application feature tests.

getconf reports configuration values defined by the operating system and its standards environment. It can answer questions such as pathname limits, maximum open files, or whether a POSIX option is supported. That is more reliable than guessing from uname or distribution names when the requirement is a standardized runtime capability.

It is not a universal capability database. A getconf variable may be unsupported, have an indeterminate value, or vary by filesystem path. The utility’s output and exit status must be interpreted according to its specification. A numeric-looking response is not automatically a safe value for arithmetic or resource allocation.

Choose a system query or a pathname query

POSIX defines two useful forms: a system configuration variable such as OPEN_MAX, or a path configuration variable followed by the pathname to inspect. For example:

getconf OPEN_MAX
getconf NAME_MAX "$target_directory"

The first asks for a system-level value. The second asks about a particular location because a filesystem can impose a different limit from another filesystem mounted on the same host. Use an existing directory representative of the location where the later operation will happen; querying . and then creating a file on a different mount answers the wrong question. NAME_MAX concerns a single filename component, not the length of a complete slash-separated path. Do not use it as a promise that a deeply nested path will fit.

PATH_MAX needs similar care. A path query describes the limit associated with the supplied location under the standard’s rules, but it does not mean every API must reject longer paths or that one fixed buffer of that size is always appropriate. Prefer APIs that grow buffers on a specific “too long” result, and operate on directory descriptors or shorter relative names when that is the right design. A reported limit describes a configuration boundary; it does not replace handling errors from the actual filesystem operation.

Interpret output and exit status together

For a valid variable that is undefined on the system, POSIX specifies the word undefined on standard output and a successful exit status. An unrecognized variable name or a query error instead produces a diagnostic and a nonzero status. Some implementations also support extensions, so read the target’s manual before depending on extra modes such as listing every variable. This distinction matters in shell: a successful command substitution does not prove that its output is a usable number.

The following pattern rejects both command failure and non-numeric output before arithmetic:

if value=$(getconf OPEN_MAX); then
    case $value in
        ''|*[!0-9]*)
            printf '%s\n' 'OPEN_MAX is not a usable decimal integer' >&2
            exit 1
            ;;
    esac
else
    printf '%s\n' 'getconf could not report OPEN_MAX' >&2
    exit 1
fi

The pattern is intentionally conservative: it rejects undefined, -1, whitespace, and implementation-specific strings rather than silently coercing them. That is suitable when the caller requires a finite nonnegative decimal value, but it is not a universal interpretation for every getconf name. An option indicator, a compiler flag string, and a pathname length are different data types. Branch on the variable’s documented meaning rather than applying numeric parsing indiscriminately.

For path-sensitive variables, also distinguish a query failure from a valid “no finite limit” result. When using the C interfaces directly, pathconf() and sysconf() can use -1 both for an error and for an indeterminate limit; the caller must clear and inspect errno to tell those cases apart. The getconf utility provides its own textual and exit-status contract, so do not copy C API return-value logic into shell code without adapting it.

Standards environments and option tests

getconf can query values associated with a standards environment using its -v option on implementations that support it. The names and guarantees are governed by platform conformance documentation. A portable script should not confuse a compile-time standards setting with the runtime utility implementation that is actually installed.

In POSIX.1-2024, -v specification selects a named compilation environment for the query; it is not a flag that turns on a shell mode or identifies the kernel. The standard describes checking the corresponding _POSIX_V8_* configuration variable before asking for values in that environment. Only use an environment the target reports as supported. Even then, do not assume the selected compiler, libraries, and runtime are interchangeable with another machine’s toolchain.

For an optional command-line flag, getconf might tell you whether the operating environment claims an associated standard option exists; it does not prove that the specific external program in PATH implements the same behavior. Check executable identity, run a safe non-mutating feature test where possible, or declare the dependency. Do not probe a dangerous option against production data.

Limits can change and checks can race

Some values are process limits or filesystem limits that differ by caller, directory, or resource. A query is not a reservation. The same process can consume descriptors after reading OPEN_MAX, and a later setrlimit(RLIMIT_NOFILE, ...) can change the soft descriptor limit represented by sysconf(_SC_OPEN_MAX). Another process consuming its own descriptors is not the relevant race for a per-process descriptor table. If the operational question is the current process’s resource limit, inspect getrlimit(RLIMIT_NOFILE) in the program or the shell’s documented ulimit interface; if the question is whether a new open will succeed, handle the result of open() itself. Do not treat OPEN_MAX as a count of currently unused descriptors.

Resource limits can also be inherited and changed by shell builtins such as ulimit, which has its own scope and portability rules. getconf reports a configuration boundary; it does not raise that boundary. Document whether the value is advisory, a hard limit, or the expected maximum the script needs to support.

Likewise, a path limit does not guarantee that a later operation will succeed: permissions may change, a mount may be replaced, a directory may disappear, or a quota may be exhausted. Keep the preflight query close to the operation, but do not make correctness depend on a check-then-use sequence. Prefer the operation’s actual success or error as the authority.

Match the tool to the question

Operational question Better evidence
What maximum filename component is reported for this directory? getconf NAME_MAX "$directory"
Does this standards environment expose a specified option? Query its documented _POSIX_* indicator, then verify the specific API or command behavior needed.
What is this process’s soft or hard descriptor limit? getrlimit(RLIMIT_NOFILE) or the active shell’s documented ulimit option.
Is there enough free disk space right now? Filesystem free-space tools and the result of the write; getconf is not a capacity meter.
Does a particular program accept an option? Check that program’s documentation/version or run a safe, non-mutating feature test. A POSIX configuration variable does not establish a third-party CLI’s behavior.

The distinction prevents an OS capability query from becoming an accidental product-level guarantee. A script that needs a particular utility’s --null flag, for example, should test or declare the utility dependency rather than infer support from the kernel name or a general POSIX profile.

Tests and operational record

Test supported, unsupported, indeterminate, and path-dependent values across each target runtime. Include a container or restricted service account where limits may differ from the login shell. Verify how target getconf distinguishes query failure from a recognized-but-undefined configuration value, and check the status as well as stdout and stderr. For pathname queries, test an existing directory on each relevant filesystem rather than assuming one host-wide answer. For resource ceilings, compare getconf with the actual process limit and then test the operation’s failure handling. Log the queried variable, relevant path, result, implementation version, and the decision the script made from it.

Use getconf to replace brittle OS-name heuristics with standardized facts. Then validate the consumer’s actual behavior and handle races at the operation itself. The query describes an environment; the program still checks whether it can safely perform the requested work.

Related:

Sources:

Comments