Я пишу простой bash-скрипт, но мне нужно проверить, запущен ли он от имени пользователя root или нет. Я знаю, что, вероятно, есть очень простой способ сделать это, но я понятия не имею, как.
Просто чтобы быть ясно:
Что простой способ , чтобы написать сценарий foo.sh , так что команда ./foo.sh
выводит 0
, и команда sudo ./foo.sh
выводит 1
?
$UID
и$EUID
есть башмизы. Просто POSIX-совместимые оболочки не имеют этих переменных, и вам нужно использовать ихid(1)
вместо этого.if ((EUID)); then
, см . комментарий @ geirhasudo
. Если вы запустите,sudo sh -c 'echo $EUID'
вы увидите ожидаемые результаты.$EUID
это Bashism (как упомянуто выше @DavidFoerster), а ваша/bin/sh
, скорее всего, является ссылкой/bin/dash
, а не/bin/bash
.sudo bash -c 'echo $EUID'
даст ожидаемый результат.Пользователь root не обязательно должен называться «root».
whoami
возвращает первое имя пользователя с идентификатором пользователя0
.$USER
содержит имя вошедшего в систему пользователя, который может иметь идентификатор пользователя0
, но иметь другое имя.Единственная надежная программа, которая проверяет, вошел ли аккаунт как root или нет:
Я использую
-u
для эффективного идентификатора пользователя, а не-r
для реального идентификатора пользователя. Права доступа определяются с помощью эффективного идентификатора пользователя, а не реальные один.тесты
/etc/passwd
содержит следующие имена пользователей с идентификатором пользователя0
в указанном порядке:Войдя в систему
root2
, дает следующие результаты:whoami
:rootx
echo $USER
:root2
(возвращает пустую строку, если программа была запущена в пустой среде, напримерenv -i sh -c 'echo $USER'
)id -u
:0
Как видите, другие программы неid -u
прошли эту проверку, только пройдены.Обновленный скрипт будет выглядеть так:
источник
id -u
в bash askubuntu.com/questions/30148/…sh
(dash
) вместо интерпретатораbash
. Но удачный выстрел спасает еще один форк :)[ -w / ]
. Идея остается прежней. Примечание: в некоторых chroot[ -w /etc/shadow ]
произойдет сбой, потому что/etc/shadow
не существует, поэтому подход с/
предпочтительным. Лучше бы проверить фактическую потребность в правах доступа root. Если сценарию необходимо выполнить запись/etc/someconfig
, просто проверьте, доступен ли для записи этот файл ИЛИ файл не существует и/etc
доступен для записи.Как сказал @Lekensteyn, вы должны использовать эффективный идентификатор пользователя. Вам не нужно звонить
id -u
в Bash:Предложение @ geirha из комментариев использует арифметическую оценку:
источник
((..))
для проверки чисел, а также[[..]]
для проверки строк и файлов, так что я бы сделалif (( EUID != 0 )); then
вместо этого, или простоif ((EUID)); then
EUID
должен стать$EUID
. Вместо использования(( $EUID != 0 ))
используйте[ $EUID != 0 ]
. С этим тоже будет работатьdash
.EUID
работает просто отлично. Вопрос маркируетсяbash
неdash
. Командаenv -i sh -c '[ $EUID != 0 ]'
не выполняется, ноenv -i bash -c '(( EUID != 0 ))'
работает. Кстати,dash
не работает для некоторых не-ascii символов в Ubuntu stackoverflow.com/questions/5160125/… Это 2011 год, и есть люди, которые используют другие языки.$EUID
материалами с этого момента. В результате я изменил принятый ответ.Вы можете сделать это с помощью
whoami
команды, которая возвращает текущего пользователя:Выполнение вышеупомянутого напечатает,
You must be root to do this.
если текущий пользователь неroot
.Примечание: альтернативой в некоторых случаях является просто проверка
$USER
переменной:источник
$USER
, особенно таким образом.$USER
устанавливается оболочкой входа в систему, она не обязательно распространяется в программу (env -i sh -c 'echo $USER'
). Таким образом,$USER
пусто и возникает синтаксическая ошибка.$USER
устанавливается оболочкой, но и легко подделывается. Whoami вернет фактического пользователя.$USER
интерпретируется вашей оболочкой, ваш пример долженsudo sh -c 'echo $USER'
быть значимым. @ Джордж: он делает неверное предположение, чтоwhoami
всегда будет возвращатьсяroot
для UID 0.Принимая во внимание эффективность, вы можете сначала протестировать
EUID
переменную окружения, а затем, если она не существует, вызвать стандартнуюid
команду:Таким образом, из-за сочетания клавиш OR вы не будете вызывать системную команду, отдавая приоритет запросу переменной в памяти.
Повторное использование кода:
источник
id -u
. Посмотрите стендовый скрипт вместе с результатами ниже его: pastebin.com/srC3LWQy((${EUID:-0} || "$(id -u)"))
всегда работаетid -u
, так же, как((1 || $(echo hi >&2; echo 1)))
и((0 || $(echo hi >&2; echo 1)))
оба печатиhi
. Арифметика внешней оболочки&&
и||
управляющие операторы; вa || "$(b)"
,b
только работает, если"$(b)"
работает. Большинство расширений, включая подстановку команд, регулируются семантикой короткого замыкания управляющих операторов. В арифметике оболочки есть операторы, которые оказались записанными по буквам,&&
а||
также - которые также являются короткими замыканиями, что((1 || 0/0))
не является ошибкой - но арифметика оболочки возникает после расширения вложенных подстановок команд.источник
Один простой способ сделать скрипт доступным только для пользователя root - запустить скрипт со строкой:
#!/bin/su root
источник
источник
Этот фрагмент будет:
sudo !!
источник
Этот ответ просто для того, чтобы сохранить идею, может быть полезным для некоторых из вас. Если вам нужен скрипт, который запускается из графического интерфейса рабочего стола и требует привилегий root, попробуйте этот способ:
Таким образом, вы получите красивое диалоговое окно с просьбой ввести пароль пользователя root. Так же, как с командной строкой sudo.
gksudo
Может быть недоступен в вашей системе , то установите егоsudo apt-get install gksu
.источник
Этот код работает как для Bash, так и для стандартного Bourne sh (протестирован под FreeBSD), который не определяет EUID. Если EUID существует, его значение возвращается, в противном случае выполняется команда 'id'. Это немного короче, чем в приведенном выше примере «или», так как в нем используется встроенная оболочка «: -».
Корень в ш:
источник