pseudo(1)

πŸ“¦
version 1.9.2+git20250711+d1db9c219abf Β· 2 versions
, in ubuntu stonking

πŸ’– NAME πŸ’–

pseudo β€” run a command in a virtual root environment 🫢

okay so this is the manual page for pseudo(1), from the General Commands Manual section, and bestie, it's a whole vibe. buckle up. πŸŽ€


✨ 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

six whole ways to summon it. we love a flexible queen πŸ‘‘


🌸 DESCRIPTION 🌸

So. The pseudo utility gives you a virtual root environment β€” from here on out we're calling it the pseudo environment, periodt β€” and it lets you create file system images and packages even though you do not have root privileges. no sudo, no gatekeeping, just vibes and files. πŸ’…

How does it do this absolute sorcery? It pushes a special library, libpseudo.so, into the LD_PRELOAD environment variable. That library intercepts a large number of common filesystem operations, plus some user-id related operations, and hands back values that look as though the operations had been performed by a root user. the audacity. the range. 🌈

All of that is then managed by a daemon program which keeps a list of virtualized file ownership and permissions β€” and that daemon program itself is pseudo. it's giving main character energy honestly.

The pseudo program itself can also be used as a program launcher. The launcher automatically configures a working environment, then executes processes within that environment. Alternatively, you can bypass this whole thing by setting up certain environment variables (see the ENVIRONMENT section below). Once that's set up, the pseudo client library (libpseudo.so) can start the server automatically. lowkey elegant. πŸ¦‹

You can invoke the pseudo command in one of several possible modes:

  • -B β€” causes pseudo to scan its database, exactly like the -C option does, but instead of reporting mismatches, pseudo tries to repair them. Specifically, device and inode number mismatches get corrected, and symlink or directory mismatches result in deletion of database entries. it's the fixer arc. πŸ”₯
  • -C β€” causes pseudo to scan its database, comparing against the filesystem, and report likely errors. heads up though: this may be unreliable when the server is actively running. πŸ‘€
  • -h β€” causes pseudo to print a usage message and exit. the classic "help me bestie" move.
  • -i β€” 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, then 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. glow-up for your paths ✨
  • -V β€” causes pseudo to print configuration information and exit immediately. info dump, no notes.
  • -S β€” 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. it's polite about it. 🫢
  • -d β€” causes pseudo to immediately detach and run in the background as a daemon. This is rarely useful except for debugging. niche use case, but we respect it.

And finally β€” invoked with none 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 default path. the chill path. 😌

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. every single one. it's a chronicler. πŸ““
  • -r root / -R root β€” Set the PSEUDO_CHROOT environment variable, running as though the program had called chroot(2) on the specified path. With -r, this implies changing the working directory to the specified directory; with -R, it does not. know the difference bestie, it matters. πŸ’œ
  • -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. it naps, it doesn't die. 😴
  • -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. stack 'em. πŸ—£οΈ
  • -x (debug) β€” Set specific debugging 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.

Case one β€” running specific commands. The usage is reasonably simple:

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

You may have to use the -Pprefix 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. πŸ“

Case two β€” 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. it just knows. ✨

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. moving day, no cap. πŸ“¦


🩺 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. like, genuinely, don't. 😭

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. so if you're seeing them... bestie, something's up. 🚨

πŸ’– ENVIRONMENT πŸ’–

okay so the two biggest env vars for pseudo are LD_PRELOAD and LD_LIBRARY_PATH. but bestie, listen β€” these don't have any special sauce for pseudo itself. they're just used the normal way to gaslight the dynamic linker into loading libpseudo so it can intercept calls into the underlying C library. πŸ’…

the following environment variables are used directly by pseudo:

  • PSEUDO_BINDIR β€” this dir holds the path to the pseudo binary. by default, it's the bin directory under PSEUDO_PREFIX. ✨
  • PSEUDO_CHROOT β€” holds the current emulated chroot(2) path. paths that are relative to this are treated as if they were relative to the filesystem root instead. 🌸
  • PSEUDO_DEBUG β€” 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. ngl 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. default is to log to standard error. if the string contains a single %s, that gets replaced with the short program name; if it contains a single %d, that gets 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 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 still intercepts them and blocks signals while processing them. this variable is reevaluated on every call to fork(2), clone(2) 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. that means 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 set, pseudo will allow fsync() and related system calls, even if 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 set, the pseudo client library calls abort() rather than setting errno to ENOSYS when there's 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's 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's 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 makes opening symlinks produce expected results in most cases. sometimes you might want to suppress this. if this variable is unset, or set to any value other than 0, pseudo expands symlink paths like this. if it's set to 0, the behavior is disabled. πŸ¦‹
  • PSEUDO_OPTS β€” holds options to be passed to any new pseudo servers started. typically, when pseudo is used as a launcher, this is set automatically. but you can also use it to pass options when using LD_PRELOAD to manually run things in the pseudo environment. πŸ‘‘
  • PSEUDO_PASSWD β€” 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's 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, this is used to determine the path 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's used as a launcher. ✨
  • PSEUDO_PROFILE_PATH β€” if pseudo was configured with profiling enabled, this specifies a path in which to write client profiling information for use with the pseudo_profile utility (not built by default). πŸ“Š
  • PSEUDO_TAG β€” if 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 are used internally to pass info 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), exec(3) 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), the behavior will be the same as if PSEUDO_DISABLED was set. for new processes, after a call to exec(3) or system(3), 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 when whole directory trees get moved, or when the underlying device and inode numbers change. 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) 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 noticeably 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 πŸ‘€


πŸ“š FURTHER READING πŸ“š

documentation of the internals of pseudo may be found in the doc subdirectory of the pseudo source tree. πŸ“–


and that's the whole vibe! the footer says pseudo - pretending to be root and pseudo(1) β€” that's the source/version and section, so you know it's official. periodt. πŸ’…βœ¨

πŸ“¦ where this page comes from