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

The install Utility: Deploy Files with Explicit Modes and Ownership

Use install deliberately to stage files and directories with declared permissions, ownership, backups, and post-deployment verification.

The install utility is commonly used by build systems and deployment scripts to copy files into final locations while setting mode and, where permitted, owner or group. It is not a POSIX-standard utility with one identical option grammar everywhere. GNU coreutils and BSD-derived implementations overlap on common flags such as -m, -o, -g, and directory creation, but details, defaults, backups, and extensions must be checked against the selected platform’s manual.

The operational advantage is that the intended destination mode can be stated explicitly instead of inherited accidentally from the source or caller’s umask. The risk is assuming that a successful copy implies an atomic, durable, semantically valid deployment. Treat install as one step in a deployment contract: stage, set ownership and mode, validate, publish or reload, and verify the resulting object.

Declare destination properties

For a program or configuration, state its destination path and intended mode:

install -d -m 0750 /srv/example
install -m 0640 app.conf /etc/example/app.conf
install -m 0755 worker /usr/local/libexec/example-worker

These modes are examples only. A config containing secrets may require a restricted owner and group; a public asset may be readable by everyone; an executable needs an execute bit but should not be writable by an untrusted service account. Use the least permission compatible with consumers. The process umask can still affect creation where a mode is not fully specified or an implementation applies it, so test exact behavior on the target platform.

Ownership flags can require elevated privilege and may fail for ordinary users. Do not ignore that status. If deployment runs as an unprivileged build user, stage artifacts under that identity and let a narrowly scoped privileged step install them. Avoid running an entire build as root just to set final ownership.

Understand copy and replacement semantics

Do not assume install is a transaction or atomic rename. Its implementation may open or replace a destination using platform-specific behavior. Existing symlinks, hard links, filesystem properties, permissions, and backup flags can affect what happens. If readers must never observe partially written content, stage a complete artifact on the destination filesystem and publish it using a separately reviewed atomic replacement protocol. For complex deployments, versioned release directories and one pointer switch are easier to roll back than overwriting a tree one file at a time.

A backup option is not a full recovery plan. Establish retention, naming, ownership, permissions, and restore procedure; ensure repeated deployment does not overwrite the only known-good copy. Do not leave backups in a directory where a service can mistake them for active configs.

Install may be inappropriate for special files, symlinks, or artifacts that must preserve ACLs, extended attributes, capabilities, labels, or timestamps. Make a metadata inventory and verify the deployed object after the operation. If these properties matter, use a deployment tool that explicitly preserves or sets them.

Validate source and destination trust boundaries

The source should be a known build artifact, not a path chosen by an untrusted caller. Verify it is a regular file if policy requires, verify its digest or signature where appropriate, and avoid race-prone validation followed by open in a hostile writable directory. Destination parent directories should have controlled ownership and permissions. A correct file mode cannot compensate for an attacker-writable parent that can replace the file.

When installing multiple source files, make clear whether each operand maps to a directory or a single target path. Quote every shell expansion so whitespace does not split operands. Protect option parsing on implementations that support –; if supporting systems without it, validate paths or make relative paths unambiguous. Do not rely on wildcard expansion to define release contents unless expansion order and unmatched-glob behavior are controlled.

Avoid permission mistakes in automation

Mode values are octal concepts but some interfaces accept symbolic modes with their own grammar. Prefer explicit numeric modes for reproducible packages when ownership and special bits are understood. Be cautious with setuid, setgid, sticky bits, and executable scripts. A file writable by its interpreter or parent directory can be changed after verification.

For a private key or token file, set restrictive permissions before the artifact becomes visible to another process. For a public executable, set ownership so the service cannot rewrite its own code. For a config, verify both file mode and every ancestor directory. Record intended owner, group, mode, path, digest, and release in deployment logs, but never log secret contents.

Validate and roll back

After installation, inspect the destination with a platform-specific metadata check and run the application’s syntax or semantic validator. Test that the service user can read the file and cannot modify it if immutability is required. Reload or restart only after validation passes; then perform a health check and confirm the new version is active.

If validation fails, restore the known-good version and verify service health again. A rollback should not depend on a backup naming convention that was never tested. For multi-file updates, decide what state is visible if step five fails after earlier files succeeded. If mixed versions are unacceptable, deploy an immutable versioned tree and switch one reference after the whole tree passes validation.

Test across implementations

Test replacement over an existing file, a missing destination, existing directory, symlink destination, read-only parent, insufficient privilege for ownership flags, umask variations, and backup behavior. Verify exact modes, owners, content, and exit statuses. Run on each supported GNU/BSD/macOS release because the utility syntax is not fully standardized. Log which executable provides install where a system may include multiple implementations.

Use install when its copy-and-mode contract is sufficient. Add explicit validation and publication logic when atomicity, rollback, metadata preservation, or concurrent readers matter. This prevents a convenient packaging utility from being mistaken for a complete deployment system.

Related:

Sources:

Comments