J'écris un script bash simple, mais j'en ai besoin pour vérifier s'il est exécuté en tant que root ou non. Je sais qu'il existe probablement un moyen très simple de le faire, mais je ne sais pas comment.
Pour être clair:
Quelle est une façon simple d'écrire un script foo.sh , de sorte que la commande des ./foo.sh
sorties 0
et la commande des sudo ./foo.sh
sorties 1
?
$UID
et$EUID
sont bashismes. Seuls les shells compatibles POSIX n'ont pas ces variables et vous devez les utiliserid(1)
.if ((EUID)); then
, voir le commentaire de @ geirhasudo
. Si vous courez,sudo sh -c 'echo $EUID'
vous verrez vos résultats escomptés.$EUID
est un bashisme (comme mentionné ci-dessus par @DavidFoerster), et vous êtes/bin/sh
probablement un lien vers/bin/dash
, pas/bin/bash
.sudo bash -c 'echo $EUID'
donnera le résultat attendu.Un utilisateur root ne doit pas nécessairement s'appeler "root".
whoami
renvoie le premier nom d'utilisateur avec l'ID utilisateur0
.$USER
contient le nom de l'utilisateur connecté, qui peut avoir un ID utilisateur0
mais un nom différent.Le seul programme fiable permettant de vérifier si le compte est connecté en tant que root ou non:
J'utilise
-u
pour l' ID utilisateur effectif , pas-r
pour l' ID utilisateur réel . Les autorisations sont déterminées par l' ID utilisateur effectif et non par le véritable .Des tests
/etc/passwd
contient les noms d'utilisateur suivants avec l'ID utilisateur0
dans l'ordre donné:Connecté en tant que
root2
, donne les résultats suivants:whoami
:rootx
echo $USER
:root2
(cela retourne une chaîne vide si le programme a été démarré dans un environnement vide, par exempleenv -i sh -c 'echo $USER'
)id -u
:0
Comme vous pouvez le constater, les autres programmes ont échoué lors de cette vérification, mais ont étéid -u
acceptés.Le script mis à jour ressemblerait à ceci:
la source
id -u
de demandersh
(dash
) comme interprète au lieu debash
. Mais bon coup, sauve une autre fourchette :)[ -w / ]
. L'idée reste la même. Remarque: dans certains chroots,[ -w /etc/shadow ]
échouera car/etc/shadow
inexistant, l’approche avec/
est préférable. Un moyen plus efficace serait de vérifier le besoin réel d'autorisations root. Si le script doit écrire/etc/someconfig
, vérifiez si ce fichier est accessible en écriture OU si le fichier n'existe pas et/etc
est accessible en écriture.Comme @Lekensteyn a dit que vous devriez utiliser un ID utilisateur efficace. Vous n'avez pas besoin d'appeler
id -u
en bash:La suggestion de @ geirha à partir des commentaires utilise l'évaluation arithmétique:
la source
((..))
pour tester les nombres, et[[..]]
pour tester les chaînes et les fichiers, donc je le ferais à laif (( EUID != 0 )); then
place, ou tout simplementif ((EUID)); then
EUID
devrait devenir$EUID
. Au lieu d'utiliser(( $EUID != 0 ))
, utilisez[ $EUID != 0 ]
. Cela fonctionneradash
aussi.EUID
fonctionne très bien. La question est étiquetéebash
pasdash
. La commandeenv -i sh -c '[ $EUID != 0 ]'
échoue, maisenv -i bash -c '(( EUID != 0 ))'
fonctionne. Au fait,dash
cela ne fonctionne pas pour certains caractères non-ASCII sur Ubuntu stackoverflow.com/questions/5160125/… Nous sommes en 2011 et il y a des gens qui utilisent d'autres langues.$EUID
suit à partir de maintenant. J'ai donc changé la réponse acceptée.Vous pouvez accomplir cela en utilisant la
whoami
commande, qui renvoie l'utilisateur actuel:L'exécution de ce qui précède imprimera
You must be root to do this.
si l'utilisateur actuel n'est pasroot
.Remarque: une alternative dans certains cas consiste simplement à vérifier la
$USER
variable:la source
$USER
, en particulier de cette façon.$USER
est défini par le shell de connexion, il n'est pas nécessaire de le propager au programme (env -i sh -c 'echo $USER'
). De cette façon,$USER
est vide et une erreur de syntaxe se produit.$USER
défini par le shell, mais il est également facile de parodier. Whoami retournera l'utilisateur réel.$USER
est interprété par votre shell, votre exemple devraitsudo sh -c 'echo $USER'
être significatif. @ George: il fait la fausse hypothèse quiwhoami
reviendra toujoursroot
pour UID 0.En prenant en compte l'efficacité, vous pouvez tester d'abord la
EUID
variable d'environnement puis, si elle n'existe pas, appeler laid
commande standard :De cette manière, en raison du raccourci OU , vous évitez d'appeler une commande système, en donnant la priorité à la requête d'une variable en mémoire.
Réutilisation du code:
la source
id -u
. Voir le script de banc avec les résultats ci-dessous ici: pastebin.com/srC3LWQy((${EUID:-0} || "$(id -u)"))
fonctionne toujoursid -u
, tout comme((1 || $(echo hi >&2; echo 1)))
et les((0 || $(echo hi >&2; echo 1)))
deux imprimerhi
. En dehors de l' arithmétique shell,&&
et||
sont des opérateurs de contrôle; dansa || "$(b)"
,b
ne fonctionne que si"$(b)"
fonctionne. La plupart des extensions, y compris la substitution de commande, sont régies par la sémantique de court-circuitage des opérateurs de contrôle. Arithmétique Shell a des opérateurs qui se passent à l' épeautre&&
et||
aussi - qui court-circuite dans ce((1 || 0/0))
n'est pas une erreur - mais SHELL arithmétique se produit après les substitutions de commandes imbriquées sont étendues.la source
Un moyen simple de rendre le script exécutable uniquement par root est de démarrer le script avec la ligne suivante:
#!/bin/su root
la source
la source
Cet extrait va:
sudo !!
la source
Cette réponse est juste pour enregistrer une idée avec peut être utile pour certains d'entre vous. Si vous avez besoin d'un script exécuté à partir de l'interface graphique du bureau et nécessitant des privilèges root, procédez comme suit:
De cette façon, vous obtiendrez une belle fenêtre de dialogue vous demandant le mot de passe de l'utilisateur root. Juste comme avec sudo en ligne de commande.
Le
gksudo
peut ne pas être disponible sur votre système puis installez-le avecsudo apt-get install gksu
.la source
Ce code fonctionne à la fois sous Bash et dans le stock Bourne sh (testé sous FreeBSD) qui ne définit pas EUID. Si EUID existe, sa valeur est renvoyée, sinon la commande 'id' est exécutée. C'est un peu plus court que l'exemple "ou" ci-dessus, car il utilise un shell intégré ": -".
Racine dans sh:
la source