Как остановить запуск скрипта, если он не является root (и вызвать эхо "Not running as root! Exiting...")

В Linux системным вызовом для установки привязки ЦП для процесса является sched_setaffinity . Еще есть инструмент набора задач , который делает это в командной строке.

Чтобы эта единственная программа работала только на одном ЦП, я думаю, вам понадобится что-то вроде

taskset -c 1 ./myprogram

(установите любой номер ЦП в качестве аргумента переключателя -c ).

Это должен быть достаточно близок к однопроцессорной системе, если другие ваши процессы не выполняются слишком много по сравнению с тем, который вы хотите измерить, или они не планируются для других процессоров. Если вы хотите выделить один ЦП только для этого единственного процесса и предотвратить запуск других процессов на этом ЦП, вам также потребуется установить их сродство.

Что, я не знаю, как делать правильно. Вам нужно будет установить привязку к процессору init на очень раннем этапе процесса загрузки, чтобы гарантировать, что она будет унаследована всеми процессами в системе. В качестве обходного пути вы можете использовать taskset -c -p 0 $ PID для всех других процессов, чтобы заставить их работать только на CPU №0.

systemd также имеет CPUAffinity = для управления привязкой в ​​файлах модулей, и есть пара из вопросов по установке привязки по умолчанию здесь, в unix.SE , но я не нашел подходящего решения.

Хотя, как прокомментировал @Kamil Maciorowski , ответил на другой вопрос о суперпользователе.com , установка isolcpus = 1 в командной строке ядра должна «изолировать этот ЦП от общих алгоритмов планирования», что может вам понадобиться.

17
01.09.2017, 00:45
4 ответа
#!/bin/sh

if [ "$(id -u)" -ne 0 ]; then
        echo 'This script must be run by root' >&2
        exit 1
fi

cat <<HEADER
Host:          $(hostname)
Time at start: $(date)

Running cache maintenance...
HEADER

swapoff -a && swapon -a
echo 1 >/proc/sys/vm/drop_caches

cat <<FOOTER
Cache maintenance done.
Time at end:   $(date)
FOOTER

Пользователь root имеет UID 0 (независимо от имени учетной записи «root» ). Если эффективный UID, возвращаемый id -u, не равен нулю, пользователь не выполняет сценарий с привилегиями root. Используйте id -ruдля проверки реального ID (UID пользователя , вызывающего скрипт ).

Не используйте $EUIDв скрипте, так как он может быть изменен непривилегированным пользователем:

$ bash -c 'echo $EUID'
1000

$ EUID=0 bash -c 'echo $EUID'
0

Если это сделает пользователь, это, очевидно, не приведет к повышению привилегий, но может привести к тому, что команды в сценарии не смогут выполнять то, что они должны делать, и файлы будут созданы с неверным владельцем и т. д.

50
27.01.2020, 19:46

Вы можете использовать $USERили whoamiдля проверки текущего пользователя.

if [[ "$USER" != "root" ]]; then
    echo "Error: script not running as root or with sudo! Exiting..."
    exit 1
fi

if [[ $(whoami) != "root" ]]; then
    echo "Warning: script must be run as root or with elevated privileges!"
    exit 1
fi

if [[ $(id -u) != "0" ]]; then
    echo "Error: script not running as root or with sudo! Exiting..."
    exit 1
fi
12
27.01.2020, 19:46

Я думаю, вам нужно скорее проверить, что у вас есть -привилегии суперпользователя, то есть что ваш эффективный идентификатор пользователя равен 0.

zshи bashделают это доступным в переменной $EUID, так что вы можете сделать:

if ((EUID != 0)); then
  echo >&2 "Error: script not running as root or with sudo! Exiting..."
  exit 1
fi

С любыми POSIX -подобными оболочками вы можете использовать idстандартную команду:

if [ "$(id -u)" -ne 0 ]; then
  echo >&2 "Error: script not running as root or with sudo! Exiting..."
  exit 1
fi

Обратите внимание, что все id -unили whoamiили переменная $USERNAMEв zshдадут вам первое имя пользователя для uid. В системах, в которых есть другие пользователи с идентификатором 0, это может быть не root, даже если процесс является потомком процесса, который был аутентифицирован как root.

$USERобычно дает вам пользователя, прошедшего аутентификацию, но полагаться на него довольно ненадежно. Он не устанавливается оболочкой, но обычно устанавливается командой аутентификации (, например login,su(в системах GNU/Linux, не обязательно другими ), sudo,sshd(командой из openssh по крайней мере )... ). Хотя (изменение uid не всегда автоматически устанавливает эту переменную, это должно быть сделано явным образом приложением, изменяющим uid ), и оно также могло быть изменено каким-либо другим процессом в предках оболочки. $LOGNAME, с той же оговоркой более надежен, так как указан в POSIX (первоначально из FIPS 151 -2)

22
27.01.2020, 19:46

На самом деле вам нужно определить, есть ли у вас доступ для выполнения этих операций. Вместо этого считается плохой практикой проверять, являетесь ли вы пользователем root.

Если система настроена таким образом, чтобы пользователь, не являющийся -пользователем root, мог изменять кэш подкачки и удалять кэш страниц, почему этот пользователь не должен запускать ваш скрипт?

Вместо этого вы можете просто попробовать операцию и выйти с полезным сообщением, если она не удалась:

if ! ( swapoff -a && swapon -a )
then
  echo "Failed to clear swap (rerun as root?)" >&2
  exit 1
fi

if ! echo 1 > /proc/sys/vm/drop_caches
then 
  echo "Failed to free page cache (rerun as root?)" >&2
  exit 1
fi
11
27.01.2020, 19:46

Теги

Похожие вопросы