В этом ответе, пусть будет ясно, я предполагаю, что читатель умеет читать bash
и сценарии оболочки POSIX, как dash
.
Я полагаю, что здесь не так много объяснений, так как высоко голосованные ответы хорошо объясняют многое из этого.
Тем не менее, если есть что-то, чтобы объяснить дальше, не стесняйтесь комментировать, я сделаю все возможное, чтобы заполнить пробелы.
Оптимизированное универсальное (не только bash
) решение для производительности и надежности; совместимы все оболочки
Новое решение:
# bool function to test if the user is root or not
is_user_root () { [ ${EUID:-$(id -u)} -eq 0 ]; }
Тест (сохранить в файл is_user_root__benchmark
)
###############################################################################
## is_user_root() benchmark ##
## Bash is fast while Dash is slow in this ##
## Tested with Dash version 0.5.8 and Bash version 4.4.18 ##
## Copyright: 2020 Vlastimil Burian ##
## E-mail: info@vlastimilburian.cz ##
## License: GPL-3.0 ##
## Revision: 1.0 ##
###############################################################################
# intentionally, the file does not have executable bit, nor it has no shebang
# to use it, please call the file directly with your shell interpreter like:
# bash is_user_root__benchmark
# dash is_user_root__benchmark
# bool function to test if the user is root or not
is_user_root () { [ ${EUID:-$(id -u)} -eq 0 ]; }
# helper functions
print_time () { date +"%T.%2N"; }
print_start () { printf '%s' 'Start : '; print_time; }
print_finish () { printf '%s' 'Finish : '; print_time; }
readonly iterations=10000
printf '%s\n' '______BENCHMARK_____'
print_start
i=1; while [ $i -lt $iterations ]; do
is_user_root
i=$((i + 1))
done
print_finish
Оригинальное решение:
#!/bin/bash
is_user_root()
# function verified to work on Bash version 4.4.18
# both as root and with sudo; and as a normal user
{
! (( ${EUID:-0} || $(id -u) ))
}
if is_user_root; then
echo 'You are the almighty root!'
else
echo 'You are just an ordinary user.'
fi
^^^ Было доказано, что зачеркнутое решение не ускоряет процесс, но оно существует уже давно, поэтому я буду держать его здесь до тех пор, пока сочту необходимым.
объяснение
Так как читать $EUID
стандартную bash
переменную в разы быстрее , эффективный номер идентификатора пользователя, чем выполнение id -u
команды для POSIX, - просто найти идентификатор пользователя, это решение объединяет оба в красиво упакованную функцию. Если и только если $EUID
по какой-либо причине недоступно, id -u
команда будет выполнена, гарантируя, что мы получим правильное возвращаемое значение независимо от обстоятельств .
Почему я публикую это решение после стольких лет, когда ФП спросил
Что ж, если я правильно вижу, кажется, что выше отсутствует фрагмент кода.
Видите ли, есть много переменных, которые должны быть приняты во внимание, и одна из них сочетает в себе производительность и надежность .
Портативное решение POSIX + Пример использования вышеуказанной функции
#!/bin/sh
# bool function to test if the user is root or not (POSIX only)
is_user_root() { [ "$(id -u)" -eq 0 ]; }
if is_user_root; then
echo 'You are the almighty root!'
exit 0 # unnecessary, but here it serves the purpose to be explicit for the readers
else
echo 'You are just an ordinary user.' >&2
exit 1
fi
Вывод
Как бы вам это ни нравилось, среда Unix / Linux очень разнообразна. Это означает, что есть люди, которые bash
так любят , что даже не думают о переносимости ( POSIX- оболочки). Другие, как я, предпочитают оболочки POSIX . В настоящее время это вопрос личного выбора и потребностей.
id -u
возвращает0
root.