How do I tell I'm running in a chroot?
What I've done here is to test whether the root of the init
process (PID 1) is the same as the root of the current process. Although /proc/1/root
is always a link to /
(unless init
itself is chrooted, but that's not a case I care about), following it leads to the “master” root directory. This technique is used in a few maintenance scripts in Debian, for example to skip starting udev after installation in a chroot.
if [ "$(stat -c %d:%i /)" != "$(stat -c %d:%i /proc/1/root/.)" ]; then
echo "We are chrooted!"
else
echo "Business as usual"
fi
(By the way, this is yet another example of why chroot
is useless for security if the chrooted process has root access. Non-root processes can't read /proc/1/root
, but they can follow /proc/1234/root
if there is a running process with PID 1234 running as the same user.)
If you do not have root permissions, you can look at /proc/1/mountinfo
and /proc/$$/mountinfo
(briefly documented in filesystems/proc.txt
in the Linux kernel documentation). This file is world-readable and contains a lot of information about each mount point in the process's view of the filesystem. The paths in that file are restricted by the chroot affecting the reader process, if any. If the process reading /proc/1/mountinfo
is chrooted into a filesystem that's different from the global root (assuming pid 1's root is the global root), then no entry for /
appears in /proc/1/mountinfo
. If the process reading /proc/1/mountinfo
is chrooted to a directory on the global root filesystem, then an entry for /
appears in /proc/1/mountinfo
, but with a different mount id. Incidentally, the root field ($4
) indicates where the chroot is in its master filesystem.
[ "$(awk '$5=="/" {print $1}' </proc/1/mountinfo)" != "$(awk '$5=="/" {print $1}' </proc/$$/mountinfo)" ]
This is a pure Linux solution. It may be generalizable to other Unix variants with a sufficiently similar /proc
(Solaris has a similar /proc/1/root
, I think, but not mountinfo
).
As mentioned in Portable way to find inode number and Detecting a chroot jail from within, you can check whether the inode number of /
is 2
:
$ ls -di /
2 /
An inode number that's different from 2 indicates that the apparent root is not the actual root of a filesystem. This will not detect chroots that happen to be rooted on a mount point, or on operating systems with random root inode numbers.
While clearly not as portable as many other options listed here, if you're on a Debian-based system, try ischroot
.
See: https://manpages.debian.org/jessie/debianutils/ischroot.1.en.html
To get the status in the console directly, using ischroot:
ischroot;echo $?
Exit codes:
0 if currently running in a chroot
1 if currently not running in a chroot
2 if the detection is not possible (On GNU/Linux this happens if the script is not run as root).