J'ai un script qui exécute trois fonctions: A && B && C
.
La fonction B
doit être exécutée en tant que super-utilisateur, tandis que A
et C
non.
J'ai plusieurs solutions mais aucune n'est satisfaisante:
sudo le script entier:
sudo 'A && B && C'
Cela semble être une mauvaise idée à exécuter
A
et enC
tant que super-utilisateur si ce n'est pas nécessairerendre le script interactif:
A && sudo B && C
Je devrai peut-être taper mon mot de passe, mais je veux que mon script ne soit pas interactif, car chaque fonction peut prendre un certain temps, et je ne veux pas que le script m'attende. Eh bien, c'est aussi pourquoi c'est un script en premier lieu, donc je n'ai pas à le regarder fonctionner.
La solution stupide:
sudo : && A && sudo -n B && C
D'abord, il semble stupide de
sudo
commencer par un no-op en premier, et je dois aussi croiser le doigt que A ne va pas en prendre plus$sudo_timeout
.Solution hypothétique (j'aimerais que vous me disiez qu'elle existe):
sudo --store-cred 'A && sudo --use-cred-from-parent-sudo B && C'
Cela demanderait mon mot de passe au début, puis n'utiliserait ces informations d'identification qu'en cas de besoin.
Quelle est votre opinion sur tout cela? Je serais très surpris qu'il n'y ait pas de solution à ce problème, car je pense que c'est un problème assez courant (qu'en est-il make all && sudo make install
)
la source
A
et . Pas de problèmes de timeout, et pas de privilèges pour A et C. Je ne pense pas que 4 soit possible, semble un "état global" pour un utilisateur.C
su -l some_non_priviliged_user
sudo
Réponses:
Je pense que la meilleure chose que vous pouvez faire est de lancer le script avec
sudo
puis de lancer explicitement les processus que vous souhaitez exécuter en tant qu'utilisateur normal avecsu user
ousudo -u user
:la source
Ajoutez votre script au
/etc/sudoers
fichier avec l'NOPASSWD
attribut, afin qu'il puisse s'exécuter sans demander de mot de passe. Vous pouvez lier cela à un utilisateur spécifique (ou à un ensemble d'utilisateurs), ou autoriser son exécutionsudo
par n'importe qui sur votre système.Un exemple de ligne pour un script appelé
/usr/local/bin/bossy
pourrait ressembler à ceciEt vous utiliseriez alors quelque chose comme ça
Pour cet exemple, je suppose que
PATH
comprend/usr/local/bin
. Sinon, utilisez simplement le chemin complet du script, c.-à-d.sudo /usr/local/bin/bossy
la source
Vous souhaiterez peut-être utiliser l'
!requiretty
option danssudo
ainsi que l'NOPASSWD
option. Mais gardez à l'esprit que cela réduit la sécurité.la source
/etc/sudoers
entrée pour l'utilisateur d'exécuter la commandeB
avecNOPASSWD
est la bonne réponse.S'appuyant sur ma réponse pour pré-autoriser sudo? (Pour qu'il puisse être exécuté plus tard) , écrivez deux scripts:
ABC_script
:B_script
:Exécuter
./ABC_script
:sudo -b ./B_script
. Cela vous demande le mot de passe ( immédiatement après avoir exécutéABC_script
). En supposant que le mot de passe correct est entré, il apparaîtB_script
dans le b ackground (car il a-b
été spécifié) en tant que root. Cela semble être équivalent àsudo sh -c "./B_script &"
.B_script
démarre en mode asynchrone, en parallèle avecABC_script
.B_script
teste l'existence d'un fichier appeléA_is_done
et boucle jusqu'à ce qu'il apparaisse.ABC_script
s'exécuteA
. Si / quand seA
termine avec succès, le script crée un fichier appeléA_is_done
.ABC_script
teste ensuite l'existence d'un fichier appeléB_is_done
et boucle jusqu'à ce qu'il apparaisse.B_script
détecte l'existenceA_is_done
et sort de la boucle. Il supprime leA_is_done
fichier et s'exécuteB
. N'oubliez pas,B_script
s'exécute en tant que root, il s'exécute donc enB
tant que root. Si / quand seB
termine avec succès, le script crée un fichier appeléB_is_done
et se ferme.ABC_script
détecte l'existenceB_is_done
et sort de la boucle. Il supprime leB_is_done
fichier. N'oubliez pas,B_script
exécuté en tant que root, ilB_is_done
appartient donc à root et vous souhaitez l'utiliserrm -f
pour éviter d'obtenir une demande de confirmation.ABC_script
puis courtC
et sort.Notes à affiner:
ABC_script
devrait probablement fonctionnerB_script
par un chemin absolu plutôt que./
.A_is_done
etB_is_done
,ABC_script
devrait probablement générer des noms de fichiers aléatoires et uniques.Il doit y avoir une disposition pour que le script en attente de rotation soit notifié si le programme qu'il attend est terminé mais a échoué. (En ce moment, en cas d'
A
échec, les deux scripts entrent simplement dans une boucle d'attente infinie.) Cela pourrait être aussi simple que de changerà
puis en modifiant les spin-waits pour lire les
X_is_done
fichiers, et continuez s'il contient 0 et quittez sinon.la source
Soyez stupide. utilisez plusieurs lignes.
la source
&&
A && sudo B && C
. Tout comme Antoine l'explique dans la question; cela ne demande pas le mot de passe jusqu'à ce qu'ilA
soit terminé, et il ne veut pas avoir à attendre cela, ni faire attendre le script.