Je veux écrire un script Shell pour automatiser une série de commandes. Le problème est que certaines commandes DOIVENT être exécutées en tant que superutilisateur et que certaines commandes NE DOIVENT PAS être exécutées en tant que superutilisateur. Ce que j'ai fait jusqu'à présent ressemble à ceci:
#!/bin/bash
command1
Sudo command2
command3
Sudo command4
Le problème est que cela signifie que quelqu'un doit attendre que la commande 1 se termine avant de demander un mot de passe. Si la commande 3 prend suffisamment de temps, il devra alors attendre que la commande 3 se termine. Ce serait bien si la personne pouvait se lever et s'en aller, puis revenir une heure plus tard et se faire. Par exemple, le script suivant a ce problème:
#!/bin/bash
sleep 310
Sudo echo "Hi, I'm root"
sleep 310
Sudo echo "I'm still root?"
Comment puis-je faire en sorte que l'utilisateur ne puisse entrer son mot de passe qu'une seule fois, au tout début, puis s'en aller?
Mise à jour:
Merci pour les réponses. J'utilise Mac OS X Lion, le script de Stephen P et les résultats sont différents: (j'ai aussi ajouté $ HOME)
pair@abbey scratch$ ./test2.sh
uid is 501
user is pair
username is
home directory is /Users/pair
pair@abbey scratch$ Sudo ./test2.sh
Password:
uid is 0
user is root
username is root
home directory is /Users/pair
Fichier sutest
#!/bin/bash
echo "uid is ${UID}"
echo "user is ${USER}"
echo "username is ${USERNAME}"
lancez-le: `./sutest 'me donne
uid is 500
user is stephenp
username is stephenp
mais en utilisant Sudo: Sudo ./sutest
donne
uid is 0
user is root
username is stephenp
Vous conservez donc le nom d'utilisateur d'origine dans $ USERNAME lors de l'exécution en tant que Sudo. Cela conduit à une solution similaire à celle affichée par les autres:
#!/bin/bash
Sudo -u ${USERNAME} normal_command_1
root_command_1
root_command_2
Sudo -u ${USERNAME} normal_command_2
# etc.
Il suffit à Sudo d’invoquer votre script, il vous demandera une fois le mot de passe.
J'ai initialement écrit cette réponse sous Linux, qui présente quelques différences avec OS X
OS X (je teste ceci sur Mountain Lion 10.8.3) a une variable d’environnement Sudo_USER
lorsque vous utilisez Sudo, qui peut être utilisée à la place de USERNAME
ci-dessus, ou pour être plus multi-plateforme, le script pourrait vérifier si Sudo_USER est défini et l'utiliser si c'est le cas, ou utiliser USERNAME s'il est défini.
Changer le script original pour OS X, il devient ...
#!/bin/bash
Sudo -u ${Sudo_USER} normal_command_1
root_command_1
root_command_2
Sudo -u ${Sudo_USER} normal_command_2
# etc.
Un premier coup de pouce pour le rendre multi-plateforme pourrait être ...
#!/bin/bash
#
# set "THE_USER" to Sudo_USER if that's set,
# else set it to USERNAME if THAT is set,
# else set it to the string "unknown"
# should probably then test to see if it's "unknown"
#
THE_USER=${Sudo_USER:-${USERNAME:-unknown}}
Sudo -u ${THE_USER} normal_command_1
root_command_1
root_command_2
Sudo -u ${THE_USER} normal_command_2
# etc.
Vous devez exécuter tout votre script en tant que superutilisateur. Si vous voulez exécuter une commande en tant que non-superutilisateur, utilisez l'option "-u" de Sudo:
#!/bin/bash
Sudo -u username command1
command2
Sudo -u username command3
command4
Lorsqu'il est exécuté en tant que root, Sudo ne demande pas de mot de passe.
Si vous utilisez ceci, vérifiez également man Sudo
:
#!/bin/bash
Sudo echo "Hi, I'm root"
Sudo -u nobody echo "I'm nobody"
Sudo -u 1000 touch /test_user
Eh bien, vous avez quelques options.
Vous pouvez configurer Sudo pour ne pas demander de mot de passe. Ceci n'est pas recommandé en raison des risques de sécurité.
Vous pouvez écrire un script attendu pour lire le mot de passe et le fournir à Sudo lorsque nécessaire, mais c'est maladroit et fragile.
Je recommanderais de concevoir le script pour qu'il s'exécute en tant que root et supprime ses privilèges chaque fois qu'ils ne sont pas nécessaires. Il suffit de l’avoir Sudo -u someotheruser command
pour les commandes qui ne nécessitent pas de root.
(S'ils doivent s'exécuter spécifiquement en tant qu'utilisateur invoquant le script, vous pouvez faire en sorte que le script enregistre l'ID utilisateur et appelle un second script via Sudo avec l'argument en argument, afin qu'il sache à qui s'adresser.)