Как скрипт может проверить, запускается ли он от имени root?

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

Просто чтобы прояснить:
Какой простой способ написать скрипт foo.sh , так что команда ./foo.sh выводит 0 и команду sudo ./foo.sh выходы 1?

91
задан 31.10.2019, 00:43

10 ответов

Этот ответ просто для того, чтобы сохранить идею, может быть полезен для некоторых из вас. Если вам нужен скрипт, который запускается из графического интерфейса рабочего стола и требует привилегий root, попробуйте следующий способ:

#!/bin/bash
if ! [ $(id -u) = 0 ]; then
   gksudo -w [110] $@
   exit
fi

#here go superuser commands, e.g. (switch intel cpu into powersave mode):
echo 1 > /sys/devices/system/cpu/intel_pstate/no_turbo
cpupower frequency-set -g powersave

Таким образом, вы получите красивое диалоговое окно с запросом пароля пользователя root. Так же, как с командной строкой sudo.

gksudo может быть недоступен в вашей системе, затем установите его с помощью sudo apt-get install gksu.

0
ответ дан 31.10.2019, 00:43

Этот фрагмент:

  • Проверка на разных сессиях
  • предлагает использовать sudo !!
  • и возвращать ошибку
[110 ]
0
ответ дан 31.10.2019, 00:44
#!/bin/bash
uid=`id -u`
if [ "$uid" == "0" ]
then
    echo 1
else
    echo 0
fi
0
ответ дан 31.10.2019, 00:44

Учитывая эффективность, вы можете сначала протестировать переменную среды EUID, а затем, если она не существует, вызвать стандартную команду id:

if ((${EUID:-0} || "$(id -u)")); then
  echo You are not root.
else
  echo Hello, root.
fi

из-за сочетания клавиш ИЛИ вы избегаете вызова системной команды, отдавая приоритет запросу переменной в памяти.

Повторное использование кода:

function amIRoot() {
  ! ((${EUID:-0} || "$(id -u)"))
}
0
ответ дан 31.10.2019, 00:45
  • 1
    +1 | Это сочетает в себе эффективность и портативность. – Matt Ball 31.10.2019, 00:46
#!/bin/bash
[[ $(id -u) != 0 ]] 
echo $?
0
ответ дан 31.10.2019, 00:46

Это можно сделать с помощью команды whoami, которая возвращает текущего пользователя:

#!/bin/bash

if [ `whoami` != 'root' ]
  then
    echo "You must be root to do this."
    exit
fi

...

При выполнении вышеизложенного будет напечатано You must be root to do this., если текущий пользователь не root. ]


Примечание: альтернативой в некоторых случаях является просто проверка переменной $USER:

if [ $USER != 'root' ]
0
ответ дан 31.10.2019, 00:47
  • 1
    @ Джордж Эдисон: я рекомендую не использовать $USER, особенно таким образом. $USER устанавливается оболочкой входа в систему, нет необходимости распространяться на программу (env -i sh -c 'echo $USER'). Таким образом, $USER пусто и возникает синтаксическая ошибка. – bob 31.10.2019, 00:47
  • 2
    @PauldeVrieze Какой смысл обманывать эту проверку? – Andrew Dalke 31.10.2019, 00:47
  • 3
    Я посмотрю на код и посмотрим, не приведет ли он к сбою сценария или что-то в этом роде. Если это сработает, я приму ваш ответ :) – Fomentia 31.10.2019, 00:48
  • 4
    Поместите это в мои сценарии, это работало прекрасно. Большое спасибо. :) – Shruti Thombre 31.10.2019, 00:48
  • 5
    @Lekensteyn Мало того, что $USER устанавливается оболочкой, это также то, что легко подделать. Whoami вернет фактического пользователя. – JesperE 31.10.2019, 00:48

Как сказал @Lekensteyn , вы должны использовать эффективный идентификатор пользователя. Вам не нужно вызывать id -u в bash:

#!/bin/bash

if [[ $EUID -ne 0 ]]; then
   echo "You must be root to do this." 1>&2
   exit 100
fi

@ В предложении @ geirha из комментариев используется арифметическая оценка:

#!/bin/bash

if (( EUID != 0 )); then
   echo "You must be root to do this." 1>&2
   exit 100
fi
0
ответ дан 31.10.2019, 00:47
  • 1
    EUID должно стать $EUID. Вместо использования (( $EUID != 0 )) используйте [ $EUID != 0 ]. Он также будет работать с dash. – MANIAK_dobrii 31.10.2019, 00:47
  • 2
    @Lekensteyn: EUID работает просто отлично. Вопрос помечен bash, а не dash. Команда env -i sh -c '[ $EUID != 0 ]' не выполняется, но env -i bash -c '(( EUID != 0 ))' работает. Кстати, dash не работает для некоторых не ascii символов в Ubuntu stackoverflow.com/questions/5160125/… Это 2011 год, и есть люди, которые используют другие языки. – Tejasvi Hegde 31.10.2019, 00:48
  • 3
    В общем случае следует использовать ((..)) для проверки чисел и [[..]] для проверки строк и файлов, поэтому вместо этого я бы сделал if (( EUID != 0 )); then или просто if ((EUID)); then – MANIAK_dobrii 31.10.2019, 00:48
  • 4
    Оглядываясь назад на это, будучи ужасно скучным и тестируя, я собираюсь использовать этот метод, как перечислено здесь, с материалом $EUID, начиная с этого момента. В результате я изменил принятый ответ. – Fomentia 31.10.2019, 00:49
  • 5
    @geirha: я добавил ваше предложение. – Community 31.10.2019, 00:49

Пользователь root не обязательно должен называться «root». whoami возвращает первое имя пользователя с идентификатором пользователя 0. $USER содержит имя вошедшего в систему пользователя, который может иметь идентификатор пользователя 0, но иметь другое имя.

Единственная надежная программа, которая проверяет, вошел ли аккаунт как root или нет:

id -u

Я использую -u для эффективного идентификатора пользователя, а не [118 ] для реального идентификатора пользователя. Разрешения определяются по эффективному идентификатору пользователя, а не по реальному .

Тесты

/etc/passwd содержат следующие имена пользователей с идентификатором пользователя 0 в указанном порядке:

rootx
root2

Войдя в систему как root2, дает следующие результаты: [ 1133]

  • whoami: rootx
  • echo $USER: root2 (возвращает пустую строку, если программа была запущена в пустой среде, например, env -i sh -c 'echo $USER') [ 1127]
  • id -u: 0 Как видите, другие программы не прошли эту проверку, только id -u прошло.

Обновленный скрипт будет выглядеть так:

#!/bin/bash
if ! [ $(id -u) = 0 ]; then
   echo "I am not root!"
   exit 1
fi
0
ответ дан 31.10.2019, 00:48

Один простой способ сделать скрипт доступным только для пользователя root - запустить скрипт со строки:
#!/bin/su root

0
ответ дан 31.10.2019, 00:48
  • 1
    Не делай этого. Он пытается войти в систему напрямую как root, тогда как sudo может потребоваться во многих системах, потому что первое запрещено. Кроме того, shebang предназначен для обеспечения того, чтобы ваш скрипт выполнялся в том виде, для которого он был спроектирован, в то время как ваш метод заставит скрипт работать в оболочке root по умолчанию, что невозможно предсказать, если скрипт запускается кем-то кроме автора. Следовательно, использование shebang для повышения привилегий скрипта серьезно нарушит его переносимость и приведет к ошибкам во многих системах. (su: Ошибка аутентификации) – Kip 31.10.2019, 00:49
#!/bin/bash
if [[ $EUID -ne 0 ]]; then
   echo "This script must be run as root" 
   exit 1
fi
0
ответ дан 31.10.2019, 00:49
  • 1
    в скрипте bash вы можете использовать if ((EUID)); then, см. комментарий @ geirha – Andrew Medico 31.10.2019, 00:50
  • 2
    @ Эндрю - я знаю, что опаздываю, но для потомков: $EUID - это Bashism (как упомянуто выше @DavidFoerster), а ваш /bin/sh, скорее всего, является ссылкой на /bin/dash, а не /bin/bash , sudo bash -c 'echo $EUID' даст ожидаемый результат. – John Kakon 31.10.2019, 00:50
  • 3
    Кроме того, $UID и $EUID являются башизмами. Просто POSIX-совместимые оболочки не имеют этих переменных, и вам нужно использовать id(1) – Daniel Galasko 31.10.2019, 00:50
  • 4
    Я принимаю эту единственную причину (после некоторого тестирования) с использованием системной переменной EUID, которая оказалась (примерно в 100 раз) быстрее, чем выполнение команды (id -u), но все ответы работали отлично. – Departamento B 31.10.2019, 00:51
  • 5
    @Andrew: переменные подставляются перед передачей в sudo. Если вы запустите sudo sh -c 'echo $EUID', вы увидите ожидаемые результаты. – Ivo Leko 31.10.2019, 00:51

Теги

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