Comment exécuter une commande 'sudo' dans un script?

84

Pour faire un patch manuellement, je dois taper cette commande

sudo ./playback_delete_data_patch.sh 09_delete_old_data_p.sql  

Il y a un espace juste avant le 09:

sudo ./playback_delete_data_patch.sh [space] 09_delete_old_data_p.sql

Comment puis-je l'exécuter dans un script?

Il existe également plusieurs autres commandes, mais celle-ci pose problème.

utilisateur251948
la source
2
Il suffit de le mettre dans le script, quel est le problème?
Lie Ryan
6
@LieRyan - le sudo mot de passe - le script ne pourra pas s'exécuter complètement si quelqu'un n'est pas là pour le saisir.
Wilf
Mon système les exécute sans problème. Ubuntu 16.04 en octobre 2017. Vous avez gâché votre sudoersconfiguration. Pas grand chose. Il faut juste réparer.
SDsolar
1
@SDsolar Votre système est celui qui a été gâché. le fait de ne pas demander le mot de passe est une vulnérabilité de sécurité mineure (rend les utilisateurs plus vulnérables à certains types d'attaques d'ingénierie sociale).
wizzwizz4

Réponses:

107

C'est rarement une bonne idée d'avoir des sudoscripts internes. Au lieu de cela, supprimez le sudodu script et exécutez-le avec sudo:

sudo myscript.sh

De cette manière, toutes les commandes du script seront exécutées avec les privilèges root et il vous suffira de donner le mot de passe une fois lors du lancement du script. Si vous avez besoin qu'une commande particulière dans le script soit exécutée sans sudoprivilèges, vous pouvez l'exécuter en tant qu'utilisateur normal avec (merci Lie Ryan ):

sudo -u username command 

L'espace est sans importance, il ne doit affecter rien, il y a toujours un espace entre une commande et ses arguments.

terdon
la source
30
il peut y avoir des commandes dans le script qui n'ont pas besoin du privilège root; vous pouvez supprimer le privilège root temporairement pour ces commandes en utilisant sudo -u username
Lie Ryan
48
Beaucoup de scripts que j'écris font toute une série d'interactions utilisateur et / ou de vérification d'erreur. Ensuite, une commande à la fin - quelque chose comme rsync - doit être exécutée en tant que root. Pourquoi voudrais-je faire en sorte que tout se passe bien et que je sois ouvert à de nombreuses lignes de code susceptibles de contenir des erreurs graves ou des vulnérabilités avec un accès root - en particulier lors du débogage - lorsqu'un seul ou plusieurs commandes nécessitent cet accès?
Joe
2
@ Joe assez juste. Changé le "jamais une bonne idée" en "rarement".
terdon
10
@ Joe a un très bon point ici. Aussi, quand on dit ne pas le faire , il serait bon de savoir exactement pourquoi est-ce, ou du moins, dans quel contexte je ne devrais pas le faire, et pourquoi
arainone
10
@terdon Vous n'écoutez pas. Je sais que si vous exécutez le script en tant que root, il ne vous demandera jamais de sudo. Je compare cela avec le fait de ne pas exécuter le script en tant que root et de placer des sudoappels explicites dans le script, car élever tout le script à la racine peut être une idée terrible s'il ne reste qu'une poignée d'actions étroites nécessitant root. Dans ce contexte, je répondais spécifiquement à votre commentaire: "En grande partie parce que cela signifie que vous ne pouvez pas exécuter le script automatiquement car vous devrez entrer le mot de passe à chaque fois que vous serez invité."
BeeOnRope
41

Vous pouvez éventuellement modifier le sudoersfichier.

Courez sudo visudo.

Ajoutez une entrée pour votre nom d'utilisateur et le script que vous souhaitez exécuter sans demander de mot de passe.

username ALL=(ALL) NOPASSWD: /path/to/script
Klaus-Dieter Warzecha
la source
2
Cela n'a pas fonctionné pour moi, mais merci, c'est bon de savoir que cela existe. J'ai peut-être mal interprété la syntaxe.
Chris K
5
Vous n'êtes pas sûr que quelqu'un en ait parlé, mais vous devez mettre fin à toutes les sessions de connexion de cet utilisateur après avoir modifié le sudoersfichier.
escape-llc
1
Pour clarifier ici, ce n’est pas le script qui contient la ligne "sudo ./playback_delete_data_patch.sh 09_delete_old_data_p.sql" qui doit être spécifiée dans le fichier sudoers, mais le script playback_delete_data_patch.sh ou toute autre commande à laquelle vous voulez attribuer cet utilisateur et / ou leur scripts pour pouvoir exécuter sudo sans spécifier de mot de passe.
MttJocy
19

Vous pouvez essayer quelque chose comme:

echo "PASSWORD" | sudo -S ./playback_delete_data_patch.sh 09_delete_old_data_p.sql

Ce n'est pas la chose la plus sûre à faire puisque vous écrivez un mot de passe sudoer en texte brut. Pour le rendre un peu plus sécurisé, vous pouvez créer une variable et lire le mot de passe sudo dans la variable, puis exécuter la commande en tant que:

echo $PASSWORD | sudo -S ./playback_delete_data_patch.sh 09_delete_old_data_p.sql

De plus, si toutes les commandes que vous exécutez ne sont pas gênantes, vous pouvez simplement exécuter votre script à l’aide sudode ce qui a été suggéré précédemment.

sudo ./myscript
Jibbers
la source
Lecture sécurisée du mot de passe dans la variable en toute sécurité:read -s PASSWORD
Tobias Uhmann
10

Cette réponse est similaire à la réponse de terdon . Je suggérerais également d'exécuter le script principal avec sudoafin que le script puisse s'exécuter sans avoir à demander le mot de passe de l'utilisateur pendant son exécution.

Toutefois, si vous souhaitez supprimer les privilèges root de certaines commandes et les exécuter en tant qu'utilisateur ayant appelé la commande sudo, vous pouvez rechercher la $SUDO_USERvariable afin de déterminer l'utilisateur d'origine.

Voici un exemple de script vous expliquant comment y parvenir:

#!/bin/bash

# ref: https://askubuntu.com/a/30157/8698
if ! [ $(id -u) = 0 ]; then
   echo "The script need to be run as root." >&2
   exit 1
fi

if [ $SUDO_USER ]; then
    real_user=$SUDO_USER
else
    real_user=$(whoami)
fi

# Commands that you don't want running as root would be invoked
# with: sudo -u $real_user
# So they will be run as the user who invoked the sudo command
# Keep in mind if the user is using a root shell (they're logged in as root),
# then $real_user is actually root
# sudo -u $real_user non-root-command

# Commands that need to be ran with root would be invoked without sudo
# root-command
Dan
la source
4

Il existe en fait un moyen beaucoup plus simple de le faire. Pour la portabilité, ceci est mon implémentation mais n'hésitez pas à le manipuler pour répondre à vos besoins.

Entrez votre mot de passe sudo en tant que paramètre lors du démarrage du script, capturez-le et renvoyez-le avec chaque commande qui vous demandera le mot de passe sudo.

#!/bin/bash

PW=$1
echo $PW | ./playback_delete_data_patch.sh 09_delete_old_data_p.sql  
./command_wo_sudo.sh <param>
echo $PW | ./other_command_requires_sudo.sh <param>

Vous pouvez ajouter une invite et capturer une fois le script lancé, comme suit:

echo "enter the sudo password, please"
read PW

Mais si quelqu'un d'autre surveille ce qui est exécuté sur le nœud; a accès aux journaux créés par celui-ci; ou est simplement en train de regarder au-dessus de votre devrait lorsque vous exécutez un test, cela pourrait compromettre la sécurité

Cela fonctionne également avec les commandes / scripts en cours d'exécution qui nécessitent un oui pour continuer:

echo $PW | yes | ./install.sh

L'écho est une réponse à une invite. Vous pouvez donc utiliser tout ce dont vous avez besoin si vous exécutez d'autres scripts comportant des invites de progression, dans un ordre séquentiel. Assurez-vous de connaître cet ordre, sinon, de mauvaises choses peuvent arriver.

csworenx
la source
C'est tellement plus élégant et simple, je suis heureux d'avoir fait défiler tout le chemin! EDIT: attendez, cela va ajouter le mot de passe à mon historique de terminal
Job
1
Comment demander un nom d'utilisateur / mot de passe avec read: ryanstutorials.net/bash-scripting-tutorial/bash-input.php Cela devrait éviter ce problème
Emploi
3
#!/bin/bash
# this declares that current user is a sudoer
sudo tee /etc/sudoers.d/$USER <<END
END

# write the content of your script here
sudo npm install hexo-cli -g
mkdir Untitled
sudo apt-get install python

# then to remove the sudo access from the current user
sudo /bin/rm /etc/sudoers.d/$USER
sudo -k
Sanyam Jain
la source
0

Vous pouvez essayer d’ajouter l’utilisateur qui exécute le script au fichier sudoers:

#give permissions to the file
sudo chmod 700 /etc/sudoers.d/useradm

sudo visudo /etc/sudoers.d/useradm

#add the following text, changing "user" but your desired user
user ALL=(ALL)NOPASSWD:ALL

#return the right permissions to the file
sudo chmod 440 /etc/sudoers.d/useradm
Evinhas
la source
Généralement c'est une mauvaise méthode. Si vous envisagez d'ajouter des règles NOPASSWD sudo, en particulier pour les comptes qui exécutent l'automatisation, vous devriez au moins les limiter à la commande exacte exécutée (et non TOUT)
Christopher Hunter