Здесь я проверил, initсовпадает ли корень процесса (PID 1) с корнем текущего процесса. Хотя /proc/1/rootэто всегда ссылка на /(если только она initне является chroot, но это не тот случай, который меня волнует), следование по ней ведет к корневому каталогу «master». Этот метод используется в нескольких сценариях обслуживания в Debian, например, для пропуска запуска udev после установки в chroot.
if [ "$(stat -c %d:%i /)" != "$(stat -c %d:%i /proc/1/root/.)" ]; then
echo "We are chrooted!"
else
echo "Business as usual"
fi
(Кстати, это еще один пример того, почему chrootбесполезно для безопасности, если у корневого процесса есть root-доступ. Процессы без полномочий root не могут читать /proc/1/root, но они могут следовать, /proc/1234/rootесли есть запущенный процесс с PID 1234, работающим так же пользователь.)
Если у вас нет прав доступа root, вы можете посмотреть /proc/1/mountinfoи /proc/$$/mountinfo(кратко описано в документации filesystems/proc.txtядра Linux ). Этот файл доступен для чтения всем и содержит много информации о каждой точке монтирования в представлении процесса файловой системы. Пути в этом файле ограничены тем, что chroot влияет на процесс чтения, если таковой имеется. Если чтение процесса /proc/1/mountinfoпривязано к файловой системе, отличной от глобального корня (при условии, что корень pid 1 является глобальным корнем), тогда запись для не /появляется /proc/1/mountinfo. Если чтение процесса /proc/1/mountinfoявляется изолированным в каталог на глобальной корневой файловой системе, то запись для /появляюсь в /proc/1/mountinfo, но с другим идентификатором монтирование. Кстати, корневое поле ($4) указывает, где находится chroot в основной файловой системе.
[ "$(awk '$5=="/" {print $1}' </proc/1/mountinfo)" != "$(awk '$5=="/" {print $1}' </proc/$$/mountinfo)" ]
Это чисто решение Linux. Это может быть обобщено на другие варианты Unix с достаточно похожим /proc(у Solaris есть подобное /proc/1/root, я думаю, но нет mountinfo).