proot [option] … [command]
Options come first, then the command to launch (/bin/sh when none is
given). This chapter collects practical recipes; the per-option detail
lives in the command-line reference.
Give proot a guest rootfs and a command:
$ proot -r ~/alpine-rootfs /bin/cat /etc/os-release
NAME="Alpine Linux"Omitting the command gives an interactive shell — the shortest way to confine a shell and all its children:
$ proot -r ~/alpine-rootfs
/ #Programs inside are still ordinary host processes (same PID namespace, same network); only their view of the filesystem is rewritten.
-b (or -m) relocates a host path into the guest view:
$ proot -b ~/alternate_hosts:/etc/hosts /bin/cat /etc/hostsBy default the guest side of a binding is dereferenced — binding over
/bin/sh actually lands on /bin/dash if /bin/sh is a symlink. Add
! to pin the bind to the link itself:
$ proot -b /bin/bash:/bin/sh! /bin/sh -c 'echo $0'
/bin/sh # but executing bash, as a file named /bin/shA bare guest rootfs cannot see /etc/resolv.conf, /dev, /proc, …
-R dir≈-r dirplus a recommended set of binds (/etc/host*,/etc/passwd,/etc/resolv.conf,/dev,/sys,/proc,/tmp,/run,$HOME, and the rootfs itself).-S dir≈-Rplus-0(fake root), with a smaller bind list chosen so package managers cannot scribble on host files. Use-Sto install packages into a guest rootfs.
$ proot -R ~/alpine-rootfs /bin/sh
$ proot -S ~/alpine-rootfs /sbin/apk add build-base$ proot -0 /usr/bin/id
uid=0(root) gid=0(root) groups=0(root)-0 intercepts identity syscalls (getuid, geteuid, getresuid,
setuid-family, chown-family, chmod/mknod/faccessat checks) and
reports success. -i 1000:1000 does the same with explicit ids.
Recorded ownership/mode changes persist in .proot-meta-file.* helper
files next to the affected files.
-0/-i and -l create .proot-meta-file.* and .proot.l2s.* files
inside the guest rootfs. -H filters them out of getdents results so
guest programs (and * expansions) never see them.
Some filesystems (SELinux-confined app storage on Android, FAT,
some FUSE mounts) deny link(2). --link2symlink records emulated
hard links as symlinks named .proot.l2s.* and reports them to guest
programs as real links.
Kernels with paranoid networking refuse bind() to ports < 1024 for
unprivileged users. -p remaps bind/connect calls to port + 1024 on
localhost sockets — a guest binding :80 actually binds :1080.
Old rootfs + new glibc occasionally hits FATAL: kernel too old, or a
program inspects uname. -k 6.1.0 rewrites the release field and
emulates selected newer-kernel syscalls (kompat extension).
Android's lstat reports misleading symlink sizes; combined with -l,
-L rewrites st_size/st_ino/link counts so emulated links look
plausible to tar, ls -l, etc.
shmget/semget/msgget families are emulated inside the tracer (a
detached --shm-helper process backs shared memory with real fds).
Each proot instance is its own IPC namespace — two proot sessions do
not share SysV objects.
-v N(orPROOT_VERBOSE=N):-1silent-but-fatal,0errors,1key decisions, up to9full syscall tracing.--kill-on-exit: kill all tracees when the main command exits — without it, orphaned/detached processes keepprootalive waiting.-w dir: initial working directory inside the guest.
| Variable | Effect |
|---|---|
PROOT_VERBOSE |
same as -v |
PROOT_TMP_DIR / TMPDIR |
directory for internal temp files (default /tmp) |
PROOT_NO_SECCOMP |
disable the seccomp accelerator (debugging) |
PROOT_ASSUME_NEW_SECCOMP |
assume kernel ≥ 4.8 seccomp semantics |
PROOT_NO_MOUNTINFO |
disable /proc/self/mountinfo rewriting |
PROOT_IGNORE_MISSING_BINDINGS |
don't fail if a -b source is missing |
PROOT_DONT_POLLUTE_ROOTFS |
store link2symlink meta-files outside the rootfs |
PROOT_LOADER |
override the injected execve loader stub |
PROOT_USE_LOADER_FOR_QEMU |
route QEMU execs through the loader stub |
PROOT_FORCE_FOREIGN_BINARY |
force foreign-ABI handling (testing) |
PROOT_FORCE_KOMPAT |
force-enable the kompat extension (testing) |
LD_* |
glibc loader variables are parsed and forwarded by the ldso emulation |
- Bindings apply to the guest path —
-b /procmeans host/procshows up at guest/proc. execveof a script re-enters translation for its shebang interpreter —-bapplies there too.- Files written into a bound directory land on the host path. There is no copy-on-write layer.
sudo,ping, realmount(2),setuidbinaries: still bound by host privileges.-0only fakes reports of privilege.