W tej odpowiedzi, niech będzie jasne, zakładam, że czytelnik jest w stanie czytać, bash
a skrypty powłoki POSIX- a takie dash
.
Uważam, że nie ma tu wiele do wyjaśnienia, ponieważ wysoko głosowane odpowiedzi dobrze tłumaczą wiele z nich.
Jeśli jednak jest coś, co można wyjaśnić dalej, nie wahaj się komentować, zrobię co w mojej mocy, aby wypełnić luki.
Zoptymalizowane kompleksowe (nie tylko bash
) rozwiązanie zapewniające wydajność i niezawodność; kompatybilne z wszystkimi powłokami
Nowe rozwiązanie:
# bool function to test if the user is root or not
is_user_root () { [ ${EUID:-$(id -u)} -eq 0 ]; }
Benchmark (zapisz do pliku 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
Oryginalne rozwiązanie:
#!/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
^^^ Udowodniono, że przekreślone rozwiązanie nie przyspiesza, ale działa już od dłuższego czasu, więc zamierzam go tu trzymać tak długo, jak będzie to konieczne.
Wyjaśnienie
Ponieważ odczytanie zmiennej $EUID
standardowej bash
, efektywnego numeru identyfikatora użytkownika jest wiele razy szybsze niż wykonanie id -u
polecenia POSIX -lyby znaleźć identyfikator użytkownika, to rozwiązanie łączy obie funkcje w ładnie zapakowaną funkcję. Jeśli i tylko wtedy, gdy $EUID
z jakiegokolwiek powodu nie jest dostępny, id -u
polecenie zostanie wykonane, zapewniając, że otrzymamy odpowiednią wartość zwracaną bez względu na okoliczności .
Dlaczego publikuję to rozwiązanie po tylu latach, o które pytał OP
Cóż, jeśli dobrze widzę, powyżej brakuje fragmentu kodu.
Widzisz, istnieje wiele zmiennych, które należy wziąć pod uwagę, a jedną z nich jest połączenie wydajności i niezawodności .
Przenośne rozwiązanie POSIX + Przykład użycia powyższej funkcji
#!/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
Wniosek
O ile ci się to nie podoba, środowisko Unix / Linux jest bardzo zróżnicowane. Oznacza to, że są ludzie, którzy bash
tak bardzo lubią , nawet nie myślą o przenośności ( powłoki POSIX ). Inni, tacy jak ja, wolą powłoki POSIX . Obecnie jest to kwestia osobistego wyboru i potrzeb.
id -u
zwraca0
root.