---
name: "pseudo"
section: "1"
platform: "linux"
package: "pseudo"
version: "1.9.0+git20220404+2b4b88eb5133-1"
release: "Debian 12 (Bookworm)"
platforms: ["linux"]
url: "https://new.carta.tech/pseudo"
---

# pseudo(1)

run a command in a virtual root environment

## NAME

pseudo - run a command in a virtual root environment

## SYNOPSIS

**pseudo** \[**-dflv**\] \[ **-x** *flags* \] \[ **-P** *prefix* \] \[ **-rR** *root* \] \[ **-t** *timeout* \] \[*command*\]

**pseudo -h**

**pseudo** \[**-dflv**\] \[ **-x** *flags* \] \[ **-P** *prefix* \] \[**-BC**\] **-i** path

**pseudo** \[**-dflv**\] \[ **-x** *flags* \] \[ **-P** *prefix* \] \[**-BC**\] **-m** from **-M** to

**pseudo** \[**-dflv**\] \[ **-x** *flags* \] \[ **-P** *prefix* \] **-S**

**pseudo** \[**-dflv**\] \[ **-x** *flags* \] \[ **-P** *prefix* \] **-V**

## DESCRIPTION

The *pseudo* utility provides a virtual root environment, hereafter referred to as the *pseudo environment*, allowing the creation of file system images and packages by users without root privileges.  The pseudo environment is implemented by pushing a special library (*libpseudo.so*) into the **LD\_PRELOAD** environment variable.  This library intercepts a large number of common filesystem operations and some user-id related operations, and returns values that look as though the operations had been performed by a root user.  This is in turn managed by a daemon program which keeps a list of virtualized file ownership and permissions; this daemon program itself is *pseudo*.

The *pseudo* program itself can also be used as a program launcher.  The launcher is used to automatically configure a working environment, then execute processes within that environment.  Alternatively, you can bypass this by setting up certain environment variables (see the **ENVIRONMENT** section below).  The *pseudo* client library (*libpseudo.so*) can then start the server automatically.

The *pseudo* command can be invoked in one of several possible modes:

- **-B**

  The **-B** option causes *pseudo* to scan its database, as with the **-C** option, but instead of reporting mismatches, *pseudo* attempts to repair them.  Specifically, device and inode number mismatches are corrected, and symlink or directory mismatches result in deletion of database entries.

- **-C**

  The **-C** option causes *pseudo* to scan its database, comparing against the filesystem, and reporting likely errors.  This may be unreliable when the server is actively running.

- **-h**

  The **-h** option causes *pseudo* to print a usage message and exit.

- **-i**

  The **-i** option causes *pseudo* to attempt to correct device number mismatches by checking inodes; if *path* has the same inode number as recorded in the database, but a different device number, all instances of the device number recorded in the database are updated to the device number in the live filesystem for *path*. This is intended to handle the mismatches that can occur when remounting an NFS filesystem.  The **-i** option implies the **-C** option.  You can also specify the **-B** option to request that the database be rebuilt.

- **-m**

  The **-m** and **-M** options cause *pseudo* to rename files, replacing the string *from* with the string *to.* The **-m** option pair implies the **-C** option.  You can also specify the **-B** option to request that the database be rebuilt.

- **-V**

  The **-V** option causes *pseudo* to print configuration information and exit immediately.

- **-S**

  The **-S** option causes *pseudo* to try to find an existing server, and if it finds one, instructs that server to shut down as soon as all clients are detached from it.  Note that the server will not shut down while clients are connected to it; in this case, *pseudo* will print a list of the remaining client PIDs.

- **-d**

  The **-d** option causes pseudo to immediately detach and run in the background as a daemon.  This is rarely useful except for debugging.

Finally, invoked without any of these options, *pseudo* sets up an emulated root environment, then invokes *command* if it was provided, otherwise a shell (using the **SHELL** environment variable if it is set, or */bin/sh* otherwise).

The following options modify the behavior of *pseudo*:

- **-d** *(daemonize)*

  Run as a daemon; *pseudo* detaches from the calling environment and runs as a daemon.  The command returns successfully if this appears to have succeeded, otherwise it produces an error message and returns a failure status.

- **-f** *(foreground)*

  Run in the foreground; *pseudo* runs as a server, and does not try to start other commands.  This mode is useful for debugging.

- **-l** *(log)*

  Enable logging.  The *pseudo* daemon will log every filesystem transaction in the log database.

- **-r** *root*

  - **-R** *root*

  Set the **PSEUDO\_CHROOT** environment variable, running as though the program had called *[chroot(2)](/chroot/2.md)* on the specified path.  With **-r**, this implies changing the working directory to the specified directory; with **-R**, it does not.

- **-t timeout**

  Set the timeout of the *pseudo* daemon, in seconds.  The default is currently 30 seconds.  After this long with no attached clients, the *pseudo* daemon shuts down automatically.  The server never shuts down while it has attached clients.  Note that this does not prevent continued use; new clients can restart the daemon if they need it.

- **-v** *(verbose)*

  Increase the verbosity of the *pseudo* daemon, and the client library for any programs started by this invocation of *pseudo*. This is equivalent to the numeric form of the **PSEUDO\_DEBUG** environment variable; multiple **-v** options increase the debugging level.

- **-x** *(debug)*

  Set specific deugging flags (the *pseudo* utility's help message lists them). This is equivalent to the string form of the **PSEUDO\_DEBUG** environment variable.

## EXAMPLES

The two most common usages of *pseudo* are using it to run specific commands, and setting up an environment manually for running various other commands.

For the first case, the usage is reasonably simple:

$ */path/to/pseudo*\
 \#  *commands which require root privileges*

You may have to use the **-P***prefix* option to tell *pseudo* where to look for its database and server.  If you specify a full path, *pseudo* assumes that **PSEUDO\_PREFIX** should be the path to the directory containing the *pseudo* program, or to the */bin* directory containing the *pseudo* program.

The other way to use *pseudo* is by setting up an environment.  This is suitable for use in *Makefiles* or similar environments, where you want to run a series of commands in the *pseudo* environment, but not to keep invoking the *pseudo* command.  To do this, set up the **PSEUDO\_PREFIX**, **LD\_PRELOAD**, and LD\_LIBRARY\_PATH environment variables, then run programs normally.  You do not need to separately invoke the *pseudo* daemon; the client library starts it as needed.

If you have moved a directory which *pseudo* was tracking, you may be able to get the database reattached using the **-m** option.  A typical usage might be:

$ */path/to/pseudo* **-B -m** *oldpath* **-M** *newpath*\

This requests that *pseudo* replace the string *oldpath* with the string *newpath* at the beginnings of filenames, then regenerate the database, correcting any device/inode numbers.

## DIAGNOSTICS

Depending on invocation, diagnostic messages usually go either to standard error or to the file **PSEUDO\_PREFIX** */var/pseudo/pseudo.log*. By default, *pseudo* daemon messages go into the log file, but messages generated by the client code go to standard error.  These can be changed using the **PSEUDO\_DEBUG\_FILE** environment variable, documented in **ENVIRONMENT**. At the default logging level, only critical messages are displayed.  If you have raised the logging level (using the *-v* option or the **PSEUDO\_DEBUG** environment variable), additional messages are displayed.  Levels higher than 2 are very unlikely to be useful outside of *pseudo* development.

Diagnostic messages seen by default are those which are believed to indicate either a serious internal flaw in *pseudo* or a completely unexpected failure from the underlying operating system.  In normal use, you should see no diagnostic messages.

## ENVIRONMENT

The most significant environment variables for *pseudo* are **LD\_PRELOAD** and **LD\_LIBRARY\_PATH**. However, these variables have no special meaning to *pseudo*; rather, they are used in the standard way to manipulate the dynamic linker into loading the *libpseudo* library so that it can intercept calls into the underlying C library.

The following environment variables are used directly by *pseudo*:

- **PSEUDO\_BINDIR**

  This directory holds the path to the *pseudo* binary; by default, it is the *bin* directory under **PSEUDO\_PREFIX.**

- **PSEUDO\_CHROOT**

  This variable holds the current emulated *[chroot(2)](/chroot/2.md)* path.  Paths that are relative to this are treated as though they were instead relative to the filesystem root.

- **PSEUDO\_DEBUG**

  This variable holds either a numeric "debug level" for *pseudo* to run at, or a set of specific debugging flags, generally letters. Use **pseudo -h** to see the available flags. In general, this is useful only for debugging *pseudo* itself.

- **PSEUDO\_DEBUG\_FILE**

  The name of a file to use for debugging messages from the pseudo client; the default is to log to standard error.  If the string contains a single **%s**, that string is replaced with the short program name, and if it contains a single **%d**, that string is replaced with the process ID.  Other format specifiers (other than '%%') are not allowed.  By default, the *pseudo* server logs to the file *pseudo.log* in the *var/pseudo* directory, while clients log to standard error.

- **PSEUDO\_DISABLED**

  If this variable is set to a value that doesn't look like f, F, n, N, s, S, or a numeric zero, the *pseudo* client library does not modify the behavior of called functions, though it continues to intercept them and block signals while processing them.  This variable is reevaluated on every call to *[fork(2)](/fork/2.md)*, *[clone(2)](/clone/2.md)* or related functions. If the value starts with a lowercase or uppercase *s* , the pseudo client disables all server spawning and communications, but still operates locally. This means that no filesystem mode or permissions changes are actually recorded or reported, but functions like *chown()* will still report success, even though nothing happens. This function is intended for debugging of issues which are complicated by the server's involvement.

- **PSEUDO\_ALLOW\_FSYNC**

  If this variable is set, pseudo will allow *fsync()* and related system calls, even it was configured with the *--enable-force-async* option. Otherwise, that option results in all such calls being discarded silently, even when **PSEUDO\_DISABLED** is set. The value specified doesn't matter.

- **PSEUDO\_ENOSYS\_ABORT**

  If this variable is set, the *pseudo* client library calls *abort()* rather than setting *errno* to **ENOSYS** in the event of a call to a missing underlying function.  This variable has no function outside of debugging *pseudo* itself.

- **PSEUDO\_LIBDIR**

  This directory holds the path to the *pseudo* shared libraries; by default, it is the *lib* directory under **PSEUDO\_PREFIX**. (On 64-bit hosts, *lib64* is also used.)

- **PSEUDO\_LOCALSTATEDIR**

  This directory holds the *pseudo* database files and log files; by default, it is the *var/pseudo* directory under **PSEUDO\_PREFIX**.

- **PSEUDO\_NOSYMLINKEXP**

  By default, when chrooted, *pseudo* prepends the chroot directory to the paths used for absolute symlinks; this behavior ensures that opening symlinks produces expected results in most cases.  In some cases you may want to suppress this.  If this variable is unset, or set to any value other than 0, *pseudo* expands symlink paths like this.  If this variable is set to 0, the behavior is disabled.

- **PSEUDO\_OPTS**

  This variable holds options to be passed to any new *pseudo* servers started.  Typically, when *pseudo* is used as a launcher, this will be set automatically; however, you can also use it to pass options when using **LD\_PRELOAD** to manually run things in the *pseudo* environment.

- **PSEUDO\_PASSWD**

  This variable holds the path to a directory containing password and group files to use for emulation of various password and group routines. It should be the path to a directory containing the *etc* directory containing files named *passwd* and *group*. When *pseudo* is emulating a *chroot* environment, the chroot directory is used by preference.  The parallelism between these cases is why this variable points at the parent directory of *etc* rather than the directory containing the files. If there is no *chroot* environment, and this variable is also unset, *pseudo* falls back to a directory specified at configure time, with the default being the root directory. This is controlled by the **PSEUDO\_PASSWD\_FALLBACK** definition.

- **PSEUDO\_PREFIX**

  If set, the variable **PSEUDO\_PREFIX** is used to determine the path to use to find the *pseudo* server, in **PSEUDO\_PREFIX**/bin, and the *pseudo* data files, in **PSEUDO\_PREFIX**/var/pseudo. This variable is automatically set by the *pseudo* program when it is used as a launcher.

- **PSEUDO\_PROFILE\_PATH**

  If *pseudo* was configured with profiling enabled, specifies a path in which to write client profiling information for use with the *pseudo\_profile* utility (not built by default).

- **PSEUDO\_TAG**

  If this variable is set in a client's environment, its value is communicated to the server at the beginning of each client session, and recorded in the log database if any logging occurs related to a specific client.  Note that different clients may have different tags associated with them; the tag value is per-client, not per-server.

- **PSEUDO\_UIDS**, **PSEUDO\_GIDS**

  These variables are used internally to pass information about the current emulated user and group identity from one process to another.

- **PSEUDO\_UNLOAD**

  This variable is reevaluated on every call to *[fork(2)](/fork/2.md)*, [exec(3)](/exec/3.md) or related functions.  If the variable exists libpseudo.so will be removed from **LD\_PRELOAD** and  **PSEUDO\_DISABLED** behavior will also be triggered.  For processes that simply  *[fork(2)](/fork/2.md),* the behavior will be the same as if  **PSEUDO\_DISABLED** was set.  For new processes, after a call to *[exec(3)](/exec/3.md) or [system(3)](/system/3.md)* pseudo will not be loaded in the new process.

- **SHELL**

  If set, this will be used when *pseudo* is invoked without either a command or one of the options which directs it to do something other than run a command.  Otherwise, *pseudo* defaults to */bin/sh .*

## BUGS

**The** *pseudo* database is not particularly robust in the face of whole directory trees being moved, or changes in the underlying device and inode numbers.  It has a reasonable chance of recovering if only the path or the device numbers have changed, but it is not particularly designed to address this.  A future release is expected to have improved resilience in these cases.

The filesystem on which *pseudo* keeps its database and files must at a minimum support UNIX domain sockets and reasonable file locking semantics.  Note that *pseudo* relies on *[flock(2)](/flock/2.md)* locking semantics; a lock has to persist into a child process.  This should probably eventually be fixed.

The *pseudo* client library is probably thread-safe, but has not been adequately tested or debugged in that context.

Filesystem performance is noticably worse under *pseudo* than it is otherwise.  This is probably because nearly every operation (other than reads and writes) involves at least one round-trip network communication with the server, and probably some kind of database activity.

## SEE ALSO

[fakeroot(1)](/fakeroot/1.md), [ld.so(8)](/ld.so/8.md), [pseudolog(1)](/pseudolog/1.md), [sqlite3(1)](/sqlite3/1.md)

## FURTHER READING

Documentation of the internals of *pseudo* may be found in the *doc* subdirectory of the pseudo source tree.
